From a7c802d8694d037024d3f4e181c11c094fcd3486 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 10:14:55 -0400 Subject: [PATCH 001/170] neigh cell mutually exclusive --- ...rep_ue_notification_eutran_neighbour_cell_meas_info.go | 4 ++-- go-apps/meep-rnis/server/rnis.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go index f7f17e536..7bd7b50a8 100644 --- a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go +++ b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go @@ -26,11 +26,11 @@ package server type MeasRepUeNotificationEutranNeighbourCellMeasInfo struct { Ecgi *Ecgi `json:"ecgi,omitempty"` // Reference Signal Received Power as defined in ETSI TS 136 214 [i.5]. - Rsrp int32 `json:"rsrp,omitempty"` + Rsrp int32 `json:"rsrp"` // Extended Reference Signal Received Power, with value mapping defined in ETSI TS 136 133 [i.16]. RsrpEx int32 `json:"rsrpEx,omitempty"` // Reference Signal Received Quality as defined in ETSI TS 136 214 [i.5]. - Rsrq int32 `json:"rsrq,omitempty"` + Rsrq int32 `json:"rsrq"` // Extended Reference Signal Received Quality, with value mapping defined in ETSI TS 136 133 [i.16]. RsrqEx int32 `json:"rsrqEx,omitempty"` // Reference Signal \"Signal to Interference plus Noise Ratio\", with value mapping defined in ETSI TS 136 133 [i.16]. diff --git a/go-apps/meep-rnis/server/rnis.go b/go-apps/meep-rnis/server/rnis.go index f538f1030..f432787f0 100644 --- a/go-apps/meep-rnis/server/rnis.go +++ b/go-apps/meep-rnis/server/rnis.go @@ -1476,6 +1476,9 @@ func checkMrNotificationRegisteredSubscriptions(key string, jsonInfo string, ext } poaInfo := convertJsonToPoaInfo(jsonInfo) + //4G and 5G neighbours information are mutually exclusive + //If at least one 5G neighbor exist, only report 5G + report5GNeighborOnly := false switch poaInfo.Type { case poaType4G: @@ -1494,9 +1497,13 @@ func checkMrNotificationRegisteredSubscriptions(key string, jsonInfo string, ext measRepUeNotificationNrNCellInfo.NrNCellGId = poaInfo.Nrcgi.NrcellId neighborCell.NrNCellInfo = append(neighborCell.NrNCellInfo, measRepUeNotificationNrNCellInfo) notif.NewRadioMeasNeiInfo = append(notif.NewRadioMeasNeiInfo, neighborCell) + report5GNeighborOnly = true default: } + if report5GNeighborOnly { + notif.EutranNeighbourCellMeasInfo = nil + } } } @@ -2021,6 +2028,7 @@ func subscriptionsPost(w http.ResponseWriter, r *http.Request) { supportedTriggerAlreadyPresent = true } } + if !supportedTriggerAlreadyPresent { subscription.FilterCriteriaAssocTri.Trigger = append(subscription.FilterCriteriaAssocTri.Trigger, TRIGGER_PERIODICAL_REPORT_STRONGEST_CELLS) } -- GitLab From 5051934af5637253b0d370f81342d42cdb43e9de Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 10:18:18 -0400 Subject: [PATCH 002/170] range --- go-packages/meep-gis-asset-mgr/asset-mgr.go | 35 +++++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/go-packages/meep-gis-asset-mgr/asset-mgr.go b/go-packages/meep-gis-asset-mgr/asset-mgr.go index 1d6b3ce05..d4ec8bbee 100644 --- a/go-packages/meep-gis-asset-mgr/asset-mgr.go +++ b/go-packages/meep-gis-asset-mgr/asset-mgr.go @@ -1954,15 +1954,21 @@ func calculatePower(subtype string, radius float32, distance float32) (rssi floa } // 4G Cellular signal strength calculator +// OFFICIAL COMPLETE RANGE // RSRP power range: -156 dBm to -44 dBm // Equivalent RSRP range: -17 to 97 // RSRQ power range: -34 dBm to 2.5 dBm // Equivalent RSRQ range: -30 to 46 +// IMPLEMENTED RANGE TO ONLY TAKE INTO ACCOUNT REAL WORLD SIGNAL STRENGHT +// RSRP power range: -100 dBm to -70 dBm +// Equivalent RSRP range: 39 to 69 +// RSRQ power range: -20 dBm to -5 dBm +// Equivalent RSRQ range: -2 to 28 // Algorithm: Linear proportion to distance over radius, if in range -const minCell4gRsrp = float32(-17) -const maxCell4gRsrp = float32(97) -const minCell4gRsrq = float32(-30) -const maxCell4gRsrq = float32(46) +const minCell4gRsrp = float32(39) +const maxCell4gRsrp = float32(69) +const minCell4gRsrq = float32(-2) +const maxCell4gRsrq = float32(28) func calculateCell4gPower(radius float32, distance float32) (rsrp float32, rsrq float32) { rsrp = minCell4gRsrp @@ -1979,11 +1985,17 @@ func calculateCell4gPower(radius float32, distance float32) (rsrp float32, rsrq // Equivalent RSRP range: 0 to 127 // RSRQ power range: -43 dBm to 20 dBm // Equivalent RSRQ range: 0 to 127 +// IMPLEMENTED RANGE TO ONLY TAKE INTO ACCOUNT REAL WORLD SIGNAL STRENGHT +// RSRP power range: -115 dBm to -65 dBm +// Equivalent RSRP range: 39 to 92 +// RSRQ power range: -20 dBm to -5 dBm (valid range actuallu -43 to 20 dB +// Equivalent RSRQ range: 47 to 77 // Algorithm: Linear proportion to distance over radius, if in range -const minCell5gRsrp = float32(0) -const maxCell5gRsrp = float32(127) -const minCell5gRsrq = float32(0) -const maxCell5gRsrq = float32(127) +// Algorithm: Linear proportion to distance over radius, if in range +const minCell5gRsrp = float32(39) +const maxCell5gRsrp = float32(92) +const minCell5gRsrq = float32(47) +const maxCell5gRsrq = float32(77) func calculateCell5gPower(radius float32, distance float32) (rsrp float32, rsrq float32) { rsrp = minCell5gRsrp @@ -1998,9 +2010,12 @@ func calculateCell5gPower(radius float32, distance float32) (rsrp float32, rsrq // WiFi signal strength calculator // Signal power range: -113 dBm to -10 dBm // Equivalent RSSI range: 0 to 100 +// IMPLEMENTED RANGE TO ONLY TAKE INTO ACCOUNT REAL WORLD SIGNAL STRENGHT +// Signal power range: -80 dBm to -30 dBm +// Equivalent RSSI range: 32 to 77 // Algorithm: Linear proportion to distance over radius, if in range -const minWifiRssi = float32(0) -const maxWifiRssi = float32(100) +const minWifiRssi = float32(32) +const maxWifiRssi = float32(77) func calculateWifiPower(radius float32, distance float32) (rssi float32) { rssi = minWifiRssi -- GitLab From 47885b1f48ee7966d5bddbe4a694a456dbb3c718 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 10:34:20 -0400 Subject: [PATCH 003/170] fix value --- go-packages/meep-gis-asset-mgr/asset-mgr.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/go-packages/meep-gis-asset-mgr/asset-mgr.go b/go-packages/meep-gis-asset-mgr/asset-mgr.go index d4ec8bbee..435dc2065 100644 --- a/go-packages/meep-gis-asset-mgr/asset-mgr.go +++ b/go-packages/meep-gis-asset-mgr/asset-mgr.go @@ -1987,12 +1987,11 @@ func calculateCell4gPower(radius float32, distance float32) (rsrp float32, rsrq // Equivalent RSRQ range: 0 to 127 // IMPLEMENTED RANGE TO ONLY TAKE INTO ACCOUNT REAL WORLD SIGNAL STRENGHT // RSRP power range: -115 dBm to -65 dBm -// Equivalent RSRP range: 39 to 92 -// RSRQ power range: -20 dBm to -5 dBm (valid range actuallu -43 to 20 dB +// Equivalent RSRP range: 42 to 92 +// RSRQ power range: -20 dBm to -5 dBm // Equivalent RSRQ range: 47 to 77 // Algorithm: Linear proportion to distance over radius, if in range -// Algorithm: Linear proportion to distance over radius, if in range -const minCell5gRsrp = float32(39) +const minCell5gRsrp = float32(42) const maxCell5gRsrp = float32(92) const minCell5gRsrq = float32(47) const maxCell5gRsrq = float32(77) -- GitLab From 5c91a0e3a7e493fe2e3299aebbb3aff45e497910 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 11:46:28 -0400 Subject: [PATCH 004/170] exclusing it only on the nr notification --- go-apps/meep-rnis/server/rnis.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/go-apps/meep-rnis/server/rnis.go b/go-apps/meep-rnis/server/rnis.go index f432787f0..45e101853 100644 --- a/go-apps/meep-rnis/server/rnis.go +++ b/go-apps/meep-rnis/server/rnis.go @@ -1476,9 +1476,6 @@ func checkMrNotificationRegisteredSubscriptions(key string, jsonInfo string, ext } poaInfo := convertJsonToPoaInfo(jsonInfo) - //4G and 5G neighbours information are mutually exclusive - //If at least one 5G neighbor exist, only report 5G - report5GNeighborOnly := false switch poaInfo.Type { case poaType4G: @@ -1497,13 +1494,8 @@ func checkMrNotificationRegisteredSubscriptions(key string, jsonInfo string, ext measRepUeNotificationNrNCellInfo.NrNCellGId = poaInfo.Nrcgi.NrcellId neighborCell.NrNCellInfo = append(neighborCell.NrNCellInfo, measRepUeNotificationNrNCellInfo) notif.NewRadioMeasNeiInfo = append(notif.NewRadioMeasNeiInfo, neighborCell) - report5GNeighborOnly = true default: } - - if report5GNeighborOnly { - notif.EutranNeighbourCellMeasInfo = nil - } } } @@ -1601,6 +1593,10 @@ func checkNrMrNotificationRegisteredSubscriptions(key string, jsonInfo string, e notif.AssociateId = append(notif.AssociateId, *assocId) + //4G and 5G neighbours information are mutually exclusive + //If at least one 5G neighbor exist, only report 5G + report5GNeighborOnly := false + strongestRsrp := int32(0) //adding the data of all reachable cells for _, poa := range ueData.InRangePoas { @@ -1637,6 +1633,8 @@ func checkNrMrNotificationRegisteredSubscriptions(key string, jsonInfo string, e } notif.NrNeighCellMeasInfo = append(notif.NrNeighCellMeasInfo, neighborCell) + report5GNeighborOnly = true + case poaType4G: var neighborCell NrMeasRepUeNotificationEutraNeighCellMeasInfo neighborCell.Rsrp = poa.Rsrp @@ -1648,6 +1646,11 @@ func checkNrMrNotificationRegisteredSubscriptions(key string, jsonInfo string, e } } + if report5GNeighborOnly { + log.Info("SIMON4 ", report5GNeighborOnly) + + notif.EutraNeighCellMeasInfo = nil + } go sendNrMrNotification(subscription.CallbackReference, notif) log.Info("Nr_Meas_Rep_Ue Notification" + "(" + subsIdStr + ")") -- GitLab From a9f41cafdf9e29083eedbe6b4bb388d6876f743a Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 11:48:08 -0400 Subject: [PATCH 005/170] removal of a log --- go-apps/meep-rnis/server/rnis.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go-apps/meep-rnis/server/rnis.go b/go-apps/meep-rnis/server/rnis.go index 45e101853..12998b408 100644 --- a/go-apps/meep-rnis/server/rnis.go +++ b/go-apps/meep-rnis/server/rnis.go @@ -1647,8 +1647,6 @@ func checkNrMrNotificationRegisteredSubscriptions(key string, jsonInfo string, e } } if report5GNeighborOnly { - log.Info("SIMON4 ", report5GNeighborOnly) - notif.EutraNeighCellMeasInfo = nil } -- GitLab From ebf1cbec3c38895c0cfc4be078c8a289015ea677 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 11:51:19 -0400 Subject: [PATCH 006/170] changing to a different PR --- ...eas_rep_ue_notification_eutran_neighbour_cell_meas_info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go index 7bd7b50a8..f7f17e536 100644 --- a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go +++ b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go @@ -26,11 +26,11 @@ package server type MeasRepUeNotificationEutranNeighbourCellMeasInfo struct { Ecgi *Ecgi `json:"ecgi,omitempty"` // Reference Signal Received Power as defined in ETSI TS 136 214 [i.5]. - Rsrp int32 `json:"rsrp"` + Rsrp int32 `json:"rsrp,omitempty"` // Extended Reference Signal Received Power, with value mapping defined in ETSI TS 136 133 [i.16]. RsrpEx int32 `json:"rsrpEx,omitempty"` // Reference Signal Received Quality as defined in ETSI TS 136 214 [i.5]. - Rsrq int32 `json:"rsrq"` + Rsrq int32 `json:"rsrq,omitempty"` // Extended Reference Signal Received Quality, with value mapping defined in ETSI TS 136 133 [i.16]. RsrqEx int32 `json:"rsrqEx,omitempty"` // Reference Signal \"Signal to Interference plus Noise Ratio\", with value mapping defined in ETSI TS 136 133 [i.16]. -- GitLab From ef347d97cfdd9932d15676a4057a6ea949a7c000 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 7 May 2021 11:58:49 -0400 Subject: [PATCH 007/170] mandatory rsrp/rsrq for 4G, 0 is valid --- ...eas_rep_ue_notification_eutran_neighbour_cell_meas_info.go | 4 ++-- ..._nr_meas_rep_ue_notification_eutra_neigh_cell_meas_info.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go index f7f17e536..7bd7b50a8 100644 --- a/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go +++ b/go-apps/meep-rnis/server/model_meas_rep_ue_notification_eutran_neighbour_cell_meas_info.go @@ -26,11 +26,11 @@ package server type MeasRepUeNotificationEutranNeighbourCellMeasInfo struct { Ecgi *Ecgi `json:"ecgi,omitempty"` // Reference Signal Received Power as defined in ETSI TS 136 214 [i.5]. - Rsrp int32 `json:"rsrp,omitempty"` + Rsrp int32 `json:"rsrp"` // Extended Reference Signal Received Power, with value mapping defined in ETSI TS 136 133 [i.16]. RsrpEx int32 `json:"rsrpEx,omitempty"` // Reference Signal Received Quality as defined in ETSI TS 136 214 [i.5]. - Rsrq int32 `json:"rsrq,omitempty"` + Rsrq int32 `json:"rsrq"` // Extended Reference Signal Received Quality, with value mapping defined in ETSI TS 136 133 [i.16]. RsrqEx int32 `json:"rsrqEx,omitempty"` // Reference Signal \"Signal to Interference plus Noise Ratio\", with value mapping defined in ETSI TS 136 133 [i.16]. diff --git a/go-apps/meep-rnis/server/model_nr_meas_rep_ue_notification_eutra_neigh_cell_meas_info.go b/go-apps/meep-rnis/server/model_nr_meas_rep_ue_notification_eutra_neigh_cell_meas_info.go index ed8d936c2..8cb7af7f0 100644 --- a/go-apps/meep-rnis/server/model_nr_meas_rep_ue_notification_eutra_neigh_cell_meas_info.go +++ b/go-apps/meep-rnis/server/model_nr_meas_rep_ue_notification_eutra_neigh_cell_meas_info.go @@ -26,9 +26,9 @@ package server type NrMeasRepUeNotificationEutraNeighCellMeasInfo struct { Ecgi *Ecgi `json:"ecgi,omitempty"` // Reference Signal Received Power as defined in ETSI TS 138 331 [i.13]. - Rsrp int32 `json:"rsrp,omitempty"` + Rsrp int32 `json:"rsrp"` // Reference Signal Received Quality as defined in ETSI TS 138 331 [i.13]. - Rsrq int32 `json:"rsrq,omitempty"` + Rsrq int32 `json:"rsrq"` // Reference Signal plus Interference Noise Ratio as defined in ETSI TS 138 331 [i.13]. Sinr int32 `json:"sinr,omitempty"` } -- GitLab From 6cc400131b36fc009bafc6659e32a0fda62f3661 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Mon, 10 May 2021 13:41:46 -0400 Subject: [PATCH 008/170] merge --- go-apps/meep-rnis/sbi/rnis-sbi.go | 59 +++++++++++++-------- go-apps/meep-rnis/server/rnis.go | 33 +++++++++++- go-packages/meep-gis-asset-mgr/asset-mgr.go | 3 ++ 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/go-apps/meep-rnis/sbi/rnis-sbi.go b/go-apps/meep-rnis/sbi/rnis-sbi.go index 69c743a31..267223885 100755 --- a/go-apps/meep-rnis/sbi/rnis-sbi.go +++ b/go-apps/meep-rnis/sbi/rnis-sbi.go @@ -29,17 +29,21 @@ import ( const moduleName string = "meep-rnis-sbi" type UeDataSbi struct { - Name string - Mnc string - Mcc string - CellId string - NrCellId string - ErabIdValid bool - AppNames []string - Latency int32 - ThroughputUL int32 - ThroughputDL int32 - PacketLoss float64 + Name string + Mnc string + Mcc string + CellId string + NrCellId string + ErabIdValid bool + AppNames []string + Latency int32 + ThroughputUL int32 + ThroughputDL int32 + PacketLoss float64 + ParentPoaName string + InRangePoas []string + InRangeRsrps []int32 + InRangeRsrqs []int32 } type PoaInfoSbi struct { @@ -326,18 +330,26 @@ func processActiveScenarioUpdate() { throughputUL = ue.NetChar.ThroughputUl } + //update measurements, don't wait for ticker + ueMeasMap, _ := sbi.gisCache.GetAllMeasurements() + poaNamesInRange, rsrpsInRange, rsrqsInRange := getMeas(name, "", ueMeasMap) + var ueDataSbi = UeDataSbi{ - Name: name, - Mnc: mnc, - Mcc: mcc, - CellId: cellId, - NrCellId: nrcellId, - ErabIdValid: erabIdValid, - AppNames: appNames, - Latency: latency, - ThroughputUL: throughputUL, - ThroughputDL: throughputDL, - PacketLoss: ploss, + Name: name, + Mnc: mnc, + Mcc: mcc, + CellId: cellId, + NrCellId: nrcellId, + ErabIdValid: erabIdValid, + AppNames: appNames, + Latency: latency, + ThroughputUL: throughputUL, + ThroughputDL: throughputDL, + PacketLoss: ploss, + ParentPoaName: poa.Name, + InRangePoas: poaNamesInRange, + InRangeRsrps: rsrpsInRange, + InRangeRsrqs: rsrqsInRange, } sbi.updateUeDataCB(ueDataSbi) } @@ -483,10 +495,12 @@ func processActiveScenarioUpdate() { } func refreshMeasurements() { + // Update UE measurements ueMeasMap, _ := sbi.gisCache.GetAllMeasurements() ueNameList := sbi.activeModel.GetNodeNames("UE") for _, name := range ueNameList { + // Ignore disconnected UEs if !isUeConnected(name) { sbi.updateMeasInfoCB(name, "", nil, nil, nil) @@ -501,6 +515,7 @@ func refreshMeasurements() { sbi.updateMeasInfoCB(name, "", nil, nil, nil) } } + } func getMeas(ue string, poaName string, ueMeasMap map[string]*gc.UeMeasurement) ([]string, []int32, []int32) { diff --git a/go-apps/meep-rnis/server/rnis.go b/go-apps/meep-rnis/server/rnis.go index f538f1030..6d230e58e 100644 --- a/go-apps/meep-rnis/server/rnis.go +++ b/go-apps/meep-rnis/server/rnis.go @@ -354,6 +354,18 @@ func updateUeData(obj sbi.UeDataSbi) { ueData.ThroughputDL = obj.ThroughputDL ueData.PacketLoss = obj.PacketLoss + var inRangePoas []InRangePoa + for index := range obj.InRangePoas { + var inRangePoa InRangePoa + inRangePoa.Name = obj.InRangePoas[index] + inRangePoa.Rsrp = obj.InRangeRsrps[index] + inRangePoa.Rsrq = obj.InRangeRsrqs[index] + inRangePoas = append(inRangePoas, inRangePoa) + } + + ueData.InRangePoas = inRangePoas + ueData.ParentPoaName = obj.ParentPoaName + oldPlmn := new(Plmn) oldPlmnMnc := "" oldPlmnMcc := "" @@ -362,6 +374,7 @@ func updateUeData(obj sbi.UeDataSbi) { oldNrPlmnMnc := "" oldNrPlmnMcc := "" oldNrCellId := "" + var oldInRangePoas []InRangePoa //get from DB jsonUeData, _ := rc.JSONGetEntry(baseKey+"UE:"+obj.Name, ".") @@ -381,9 +394,10 @@ func updateUeData(obj sbi.UeDataSbi) { oldNrPlmnMcc = ueDataObj.Nrcgi.Plmn.Mcc oldNrCellId = ueDataObj.Nrcgi.NrcellId } - + oldInRangePoas = ueDataObj.InRangePoas } } + //updateDB if changes occur (4G section) if newEcgi.Plmn.Mnc != oldPlmnMnc || newEcgi.Plmn.Mcc != oldPlmnMcc || newEcgi.CellId != oldCellId { @@ -425,6 +439,23 @@ func updateUeData(obj sbi.UeDataSbi) { //update because nrcgi changed _ = rc.JSONSetEntry(baseKey+"UE:"+obj.Name, ".", convertUeDataToJson(&ueData)) } + //update if poa in range and signal powers changed + //as soon as there is one difference... need an update + updateMeas := false + if len(oldInRangePoas) != len(inRangePoas) { + updateMeas = true + } else { + for index := range oldInRangePoas { + if oldInRangePoas[index].Name != inRangePoas[index].Name || oldInRangePoas[index].Rsrp != inRangePoas[index].Rsrp || oldInRangePoas[index].Rsrq != inRangePoas[index].Rsrq { + updateMeas = true + break + } + } + } + if updateMeas { + //update because power signals changed + _ = rc.JSONSetEntry(baseKey+"UE:"+obj.Name, ".", convertUeDataToJson(&ueData)) + } } } diff --git a/go-packages/meep-gis-asset-mgr/asset-mgr.go b/go-packages/meep-gis-asset-mgr/asset-mgr.go index 1d6b3ce05..e749c3013 100644 --- a/go-packages/meep-gis-asset-mgr/asset-mgr.go +++ b/go-packages/meep-gis-asset-mgr/asset-mgr.go @@ -1839,6 +1839,9 @@ func (am *AssetMgr) updateUeInfo(ueMap map[string]*Ue) (err error) { for poaName, meas := range ue.Measurements { // Calculate power measurements rssi, rsrp, rsrq := calculatePower(meas.SubType, meas.Radius, meas.Distance) + if rsrp == 0 && rsrq == 0 { + log.Error("ERROR: Zero Rsrp and RsRq should not happen: ", meas.SubType, "---", meas.Radius, "---", meas.Distance, "---", poaName, "---", ueName) + } // Add new entry or update existing one id := ueName + "-" + poaName -- GitLab From d857756a354adecd6fafa8768dcd719e66729c8e Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Wed, 12 May 2021 13:43:17 -0400 Subject: [PATCH 009/170] influx first merge --- go-apps/meep-gis-engine/server/gis-engine.go | 52 ++- go-packages/meep-gis-cache/convert.go | 50 +++ go-packages/meep-gis-cache/gis-cache.go | 81 ++++- go-packages/meep-gis-cache/gis.go | 319 +++++++++++++++++++ 4 files changed, 498 insertions(+), 4 deletions(-) create mode 100644 go-packages/meep-gis-cache/convert.go create mode 100644 go-packages/meep-gis-cache/gis.go diff --git a/go-apps/meep-gis-engine/server/gis-engine.go b/go-apps/meep-gis-engine/server/gis-engine.go index c7622f7ae..bffdbfd53 100644 --- a/go-apps/meep-gis-engine/server/gis-engine.go +++ b/go-apps/meep-gis-engine/server/gis-engine.go @@ -39,6 +39,7 @@ import ( const serviceName = "GIS Engine" const moduleName = "meep-gis-engine" const redisAddr = "meep-redis-master.default.svc.cluster.local:6379" +const influxAddr = "http://meep-influxdb.default.svc.cluster.local:8086" const sboxCtrlBasepath = "http://meep-sandbox-ctrl/sandbox-ctrl/v1" const postgisUser = "postgres" const postgisPwd = "pwd" @@ -93,6 +94,7 @@ type GisEngine struct { automation map[string]bool automationTicker *time.Ticker updateTime time.Time + snapshotTicker *time.Ticker mutex sync.Mutex } @@ -260,6 +262,23 @@ func processScenarioActivate() { // Update Gis cache updateCache() + + // Start snapshot thread + if ge.activeModel.GetScenarioName() != "" { + err := ge.StartSnapshotThread() + if err != nil { + log.Error("Failed to start snapshot thread: " + err.Error()) + return + } else { + // Connect to GIS cache + err = ge.gisCache.UpdateGisCacheInflux(ge.sandboxName, ge.activeModel.GetScenarioName(), influxAddr) + if err != nil { + log.Error("Failed to GIS Cache: ", err.Error()) + } else { + log.Info("Connected to GIS Cache") + } + } + } } func processScenarioUpdate() { @@ -293,6 +312,9 @@ func processScenarioTerminate() { // Sync with active scenario store ge.activeModel.UpdateScenario() + // Stop snapshot thread + ge.StopSnapshotThread() + // Stop automation resetAutomation() @@ -797,7 +819,8 @@ func updateCache() { measurement.Rssi = ueMeas.Rssi measurement.Rsrp = ueMeas.Rsrp measurement.Rsrq = ueMeas.Rsrq - _ = ge.gisCache.SetMeasurement(ue.Name, ueMeas.Poa, measurement) + measurement.Distance = ueMeas.Distance + _ = ge.gisCache.SetMeasurement(ue.Name, ueMeas.SubType, ueMeas.Poa, measurement) } } } @@ -1297,3 +1320,30 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) } + +func (ge *GisEngine) StartSnapshotThread() error { + // Make sure ticker is not already running + if ge.snapshotTicker != nil { + return errors.New("ticker already running") + } + + // Create new ticker and start snapshot thread + ge.snapshotTicker = time.NewTicker(time.Second) + go func() { + for range ge.snapshotTicker.C { + if ge.gisCache != nil { + + ge.gisCache.TakeUeMetricSnapshot() + } + } + }() + + return nil +} + +func (ge *GisEngine) StopSnapshotThread() { + if ge.snapshotTicker != nil { + ge.snapshotTicker.Stop() + ge.snapshotTicker = nil + } +} diff --git a/go-packages/meep-gis-cache/convert.go b/go-packages/meep-gis-cache/convert.go new file mode 100644 index 000000000..5cc6297d6 --- /dev/null +++ b/go-packages/meep-gis-cache/convert.go @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 InterDigital Communications, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package giscache + +import ( + "encoding/json" + "strconv" +) + +func JsonNumToInt32(num json.Number) (val int32) { + if intVal, err := strconv.Atoi(num.String()); err == nil { + val = int32(intVal) + } + return val +} + +func JsonNumToFloat64(num json.Number) (val float64) { + if floatVal, err := num.Float64(); err == nil { + val = floatVal + } + return val +} + +func StrToInt32(str string) (val int32) { + if intVal, err := strconv.Atoi(str); err == nil { + val = int32(intVal) + } + return val +} + +func StrToFloat64(str string) (val float64) { + if floatVal, err := strconv.ParseFloat(str, 64); err == nil { + val = floatVal + } + return val +} diff --git a/go-packages/meep-gis-cache/gis-cache.go b/go-packages/meep-gis-cache/gis-cache.go index 15201cbac..a3f9c04cb 100644 --- a/go-packages/meep-gis-cache/gis-cache.go +++ b/go-packages/meep-gis-cache/gis-cache.go @@ -20,12 +20,16 @@ import ( "fmt" "strconv" "strings" + "time" dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis" + influx "github.com/influxdata/influxdb1-client/v2" ) +const defaultInfluxDBAddr = "http://meep-influxdb.default.svc.cluster.local:8086" +const dbMaxRetryCount = 2 const redisTable = 0 const ( @@ -35,11 +39,15 @@ const ( ) const ( + fieldDistance = "distance" fieldLatitude = "lat" fieldLongitude = "long" + fieldPoa = "poa" + fieldPoaType = "poatype" fieldRssi = "rssi" fieldRsrp = "rsrp" fieldRsrq = "rsrq" + fieldSrc = "src" ) const ( @@ -61,11 +69,14 @@ type Measurement struct { Rssi float32 Rsrp float32 Rsrq float32 + Distance float32 } type GisCache struct { - rc *redis.Connector - baseKey string + rc *redis.Connector + influxName string + influxClient *influx.Client + baseKey string } // NewGisCache - Creates and initialize a GIS Cache instance @@ -88,6 +99,59 @@ func NewGisCache(sandboxName string, redisAddr string) (gc *GisCache, err error) return gc, nil } +// UpdateGisCacheInflux - Creates and initialize an Influx DB for a GIS Cache instance +func (gc *GisCache) UpdateGisCacheInflux(sandboxName string, scenarioName string, influxAddr string) (err error) { + // Connect to Influx DB + for retry := 0; gc.influxClient == nil && retry <= dbMaxRetryCount; retry++ { + gc.influxClient, err = gc.connectInfluxDB(influxAddr) + if err != nil { + log.Warn("Failed to connect to InfluxDB. Retrying... Error: ", err) + } + } + if err != nil { + return err + } + log.Info("Connected to GIS Cache Influx DB") + + influxName := sandboxName + if scenarioName != "" { + influxName = influxName + "_" + scenarioName + } + + gc.influxName = strings.Replace(influxName, "-", "_", -1) + + err = gc.CreateInfluxDb() + if err != nil { + log.Info("Error in creating influx db") + } + + //nil or not + return err +} + +func (gc *GisCache) connectInfluxDB(addr string) (*influx.Client, error) { + if addr == "" { + addr = defaultInfluxDBAddr + } + log.Debug("InfluxDB Connector connecting to ", addr) + + client, err := influx.NewHTTPClient(influx.HTTPConfig{Addr: addr, InsecureSkipVerify: true}) + if err != nil { + log.Error("InfluxDB Connector unable to connect ", addr) + return nil, err + } + defer client.Close() + + _, version, err := client.Ping(1000 * time.Millisecond) + if err != nil { + log.Error("InfluxDB Connector unable to connect ", addr) + return nil, err + } + + log.Info("InfluxDB Connector connected to ", addr, " version: ", version) + return &client, nil +} + // SetPosition - Create or update entry in DB func (gc *GisCache) SetPosition(typ string, name string, position *Position) error { key := gc.baseKey + posKey + typ + ":" + name @@ -153,14 +217,19 @@ func (gc *GisCache) DelPosition(typ string, name string) { } // SetMeasurement - Create or update entry in DB -func (gc *GisCache) SetMeasurement(ue string, poa string, meas *Measurement) error { +func (gc *GisCache) SetMeasurement(ue string, poaType string, poa string, meas *Measurement) error { key := gc.baseKey + measKey + ue + ":" + poa // Prepare data fields := make(map[string]interface{}) + fields[fieldSrc] = fmt.Sprintf("%s", ue) + fields[fieldPoa] = fmt.Sprintf("%s", poa) + fields[fieldPoaType] = fmt.Sprintf("%s", poaType) fields[fieldRssi] = fmt.Sprintf("%f", meas.Rssi) fields[fieldRsrp] = fmt.Sprintf("%f", meas.Rsrp) fields[fieldRsrq] = fmt.Sprintf("%f", meas.Rsrq) + fields[fieldDistance] = fmt.Sprintf("%f", meas.Distance) + // Update entry in DB err := gc.rc.SetEntry(key, fields) @@ -215,6 +284,10 @@ func getMeasurement(key string, fields map[string]string, userData interface{}) if rsrq, err := strconv.ParseFloat(fields[fieldRsrq], 32); err == nil { meas.Rsrq = float32(rsrq) } + if distance, err := strconv.ParseFloat(fields[fieldDistance], 32); err == nil { + meas.Distance = float32(distance) + } + // Add measurement to map ueMeas, found := measurementMap[ueName] @@ -239,4 +312,6 @@ func (gc *GisCache) DelMeasurement(ue string, poa string) { // Flush - Remove all GIS cache entries func (gc *GisCache) Flush() { gc.rc.DBFlush(gc.baseKey) + + gc.FlushInfluxDb() } diff --git a/go-packages/meep-gis-cache/gis.go b/go-packages/meep-gis-cache/gis.go new file mode 100644 index 000000000..d0b36152b --- /dev/null +++ b/go-packages/meep-gis-cache/gis.go @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2021 InterDigital Communications, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package giscache + +import ( + "errors" + "strconv" + "strings" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + influx "github.com/influxdata/influxdb1-client/v2" +) + +const UeMetName = "meas" +const UeMetNameInflux = "gis" +const UeMetSrc = "src" +const UeMetPoa = "poa" +const UeMetPoaType = "poatype" +const UeMetRssi = "rssi" +const UeMetRsrp = "rsrp" +const UeMetRsrq = "rsrq" +const UeMetDistance = "distance" +const UeMetTime = "time" + +type Metric struct { + Name string + Tags map[string]string + Fields map[string]interface{} +} + +type UeMetric struct { + Src string + Poa string + PoaType string + Time interface{} + Rssi int32 + Rsrp int32 + Rsrq int32 + Distance float64 +} + +// SetInfluxMetric - Generic metric setter +func (gc *GisCache) SetInfluxMetric(metricList []Metric) error { + if gc.influxClient == nil { + return errors.New("Not connected to Influx DB") + } + + // Create a new point batch + bp, _ := influx.NewBatchPoints(influx.BatchPointsConfig{ + Database: gc.influxName, + Precision: "ns", + }) + + // Create & add points to batch + for _, metric := range metricList { + pt, err := influx.NewPoint(metric.Name, metric.Tags, metric.Fields) + if err != nil { + log.Error("Failed to create point with error: ", err) + return err + } + bp.AddPoint(pt) + } + + // Write the batch + err := (*gc.influxClient).Write(bp) + if err != nil { + log.Error("Failed to write point with error: ", err) + return err + } + return nil +} + +// GetInfluxMetric - Generic metric getter +func (gc *GisCache) GetInfluxMetric(metric string, tags map[string]string, fields []string, duration string, count int) (values []map[string]interface{}, err error) { + if gc.influxClient == nil { + return values, errors.New("Not connected to Influx DB") + } + + // Create query + + // Fields + fieldStr := "" + for _, field := range fields { + if fieldStr == "" { + fieldStr = field + } else { + fieldStr += "," + field + } + } + if fieldStr == "" { + fieldStr = "*" + } + + // Tags + tagStr := "" + for k, v := range tags { + mv := strings.Split(v, ",") + + if tagStr == "" { + tagStr = " WHERE (" // + k + "='" + v + "'" + } else { + tagStr += " AND (" //+ k + "='" + v + "'" + } + for i, v := range mv { + if i != 0 { + tagStr += " OR " + } + tagStr += k + "='" + v + "'" + } + tagStr += ")" + } + if duration != "" { + if tagStr == "" { + tagStr = " WHERE time > now() - " + duration + } else { + tagStr += " AND time > now() - " + duration + } + } + + // Count + countStr := "" + if count != 0 { + countStr = " LIMIT " + strconv.Itoa(count) + } + + query := "SELECT " + fieldStr + " FROM " + metric + " " + tagStr + " ORDER BY desc" + countStr + log.Debug("QUERY: ", query) + + // Query store for metric + q := influx.NewQuery(query, gc.influxName, "") + response, err := (*gc.influxClient).Query(q) + if err != nil { + log.Error("Query failed with error: ", err.Error()) + return values, err + } + + // Process response + if len(response.Results) > 0 && len(response.Results[0].Series) > 0 { + row := response.Results[0].Series[0] + for _, qValues := range row.Values { + rValues := make(map[string]interface{}) + for index, qVal := range qValues { + rValues[row.Columns[index]] = qVal + } + values = append(values, rValues) + } + } + + return values, nil +} + +func (gc *GisCache) formatCachedUeMetric(values map[string]interface{}) (metric UeMetric, err error) { + var ok bool + var val interface{} + + // Process field values + if val, ok = values[UeMetSrc]; !ok { + val = "" + } + metric.Src = val.(string) + + if val, ok = values[UeMetPoa]; !ok { + val = "" + } + metric.Poa = val.(string) + + if val, ok = values[UeMetPoaType]; !ok { + val = "" + } + metric.PoaType = val.(string) + + if val, ok = values[UeMetRssi]; !ok { + val = "" + } + rssi := StrToFloat64(val.(string)) + metric.Rssi = int32(rssi) + + if val, ok = values[UeMetRsrp]; !ok { + val = "" + } + rsrp := StrToFloat64(val.(string)) + metric.Rsrp = int32(rsrp) + + if val, ok = values[UeMetRsrq]; !ok { + val = "" + } + rsrq := StrToFloat64(val.(string)) + metric.Rsrq = int32(rsrq) + + if val, ok = values[UeMetDistance]; !ok { + val = "" + } + metric.Distance = StrToFloat64(val.(string)) + + return metric, nil +} + +// GetRedisMetric - Generic metric getter +func (gc *GisCache) GetRedisMetric(metric string, tagStr string) (values []map[string]interface{}, err error) { + if gc.rc == nil { + err = errors.New("Redis metrics DB not accessible") + return values, err + } + + // Get latest metrics + key := gc.baseKey + metric + ":" + tagStr + + err = gc.rc.ForEachEntry(key, gc.getMetricsEntryHandler, &values) + if err != nil { + log.Error("Failed to get entries: ", err) + return nil, err + } + return values, nil +} + +func (gc *GisCache) getMetricsEntryHandler(key string, fields map[string]string, userData interface{}) error { + // Retrieve field values + values := make(map[string]interface{}) + for k, v := range fields { + values[k] = v + } + // Append values list to data + data := userData.(*[]map[string]interface{}) + *data = append(*data, values) + + return nil +} + +func (gc *GisCache) TakeUeMetricSnapshot() { + // start = time.Now() + + // Get all cached metrics + valuesArray, err := gc.GetRedisMetric(UeMetName, "*") + if err != nil { + log.Error("Failed to retrieve metrics with error: ", err.Error()) + return + } + + // logTimeLapse("GetRedisMetric wildcard") + + // Prepare ue metrics list + metricList := make([]Metric, len(valuesArray)) + for index, values := range valuesArray { + // Format network metric + nm, err := gc.formatCachedUeMetric(values) + if err != nil { + continue + } + + // Add metric to list + metric := &metricList[index] + metric.Name = UeMetNameInflux + metric.Tags = map[string]string{UeMetSrc: nm.Src, UeMetPoa: nm.Poa, UeMetPoaType: nm.PoaType} + metric.Fields = map[string]interface{}{ + UeMetRssi: nm.Rssi, + UeMetRsrp: nm.Rsrp, + UeMetRsrq: nm.Rsrq, + UeMetDistance: nm.Distance, + } + } + + // Store metrics in influx + err = gc.SetInfluxMetric(metricList) + if err != nil { + log.Error("Fail to write influx metrics with error: ", err.Error()) + } + + // logTimeLapse("Write to Influx") +} + +// CreateInfluxDb - +func (gc *GisCache) CreateInfluxDb() error { + + if gc.influxName != "" { + + // Create new DB if necessary + if gc.influxClient != nil { + q := influx.NewQuery("CREATE DATABASE "+ gc.influxName, "", "") + _, err := (*gc.influxClient).Query(q) + if err != nil { + log.Error("Query failed with error: ", err.Error()) + return err + } + } + } else { + log.Error("Nil influxDbName") + } + + log.Info("Influx database ", gc.influxName, " created") + + return nil +} + +// FlushInfluxDb - +func (gc *GisCache) FlushInfluxDb() { + // Flush Influx DB + if gc.influxClient != nil { + q := influx.NewQuery("DROP SERIES FROM /.*/", gc.influxName, "") + response, err := (*gc.influxClient).Query(q) + if err != nil { + log.Error("Query failed with error: ", err.Error()) + } + log.Info(response.Results) + } +} -- GitLab From 5e4d290bad5cd4abf26d09eb228debf76e97cb95 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 14 May 2021 15:17:31 -0400 Subject: [PATCH 010/170] splitting in 2 influx measurement types --- go-apps/meep-gis-engine/server/gis-engine.go | 4 +- go-packages/meep-gis-cache/gis-cache.go | 76 +++++++------- go-packages/meep-gis-cache/gis.go | 102 +++++++++++-------- 3 files changed, 102 insertions(+), 80 deletions(-) diff --git a/go-apps/meep-gis-engine/server/gis-engine.go b/go-apps/meep-gis-engine/server/gis-engine.go index bffdbfd53..bdbf08627 100644 --- a/go-apps/meep-gis-engine/server/gis-engine.go +++ b/go-apps/meep-gis-engine/server/gis-engine.go @@ -809,7 +809,7 @@ func updateCache() { updateRequired = true } else { cachedMeas, found := cachedUeMeas.Measurements[ueMeas.Poa] - if !found || cachedMeas.Rssi != ueMeas.Rssi || cachedMeas.Rsrp != ueMeas.Rsrp || cachedMeas.Rsrq != ueMeas.Rsrq { + if !found || cachedMeas.Distance != ueMeas.Distance || cachedMeas.Rssi != ueMeas.Rssi || cachedMeas.Rsrp != ueMeas.Rsrp || cachedMeas.Rsrq != ueMeas.Rsrq { updateRequired = true } } @@ -820,7 +820,7 @@ func updateCache() { measurement.Rsrp = ueMeas.Rsrp measurement.Rsrq = ueMeas.Rsrq measurement.Distance = ueMeas.Distance - _ = ge.gisCache.SetMeasurement(ue.Name, ueMeas.SubType, ueMeas.Poa, measurement) + _ = ge.gisCache.SetMeasurement(ue.Name, AssetTypeUe, ueMeas.Poa, ueMeas.SubType, measurement) } } } diff --git a/go-packages/meep-gis-cache/gis-cache.go b/go-packages/meep-gis-cache/gis-cache.go index a3f9c04cb..118706003 100644 --- a/go-packages/meep-gis-cache/gis-cache.go +++ b/go-packages/meep-gis-cache/gis-cache.go @@ -39,15 +39,16 @@ const ( ) const ( - fieldDistance = "distance" + fieldDistance = "dist" fieldLatitude = "lat" fieldLongitude = "long" - fieldPoa = "poa" - fieldPoaType = "poatype" + fieldDest = "dest" + fieldDestType = "destType" fieldRssi = "rssi" fieldRsrp = "rsrp" fieldRsrq = "rsrq" - fieldSrc = "src" + fieldSrc = "src" + fieldSrcType = "srcType" ) const ( @@ -66,9 +67,9 @@ type UeMeasurement struct { } type Measurement struct { - Rssi float32 - Rsrp float32 - Rsrq float32 + Rssi float32 + Rsrp float32 + Rsrq float32 Distance float32 } @@ -101,26 +102,26 @@ func NewGisCache(sandboxName string, redisAddr string) (gc *GisCache, err error) // UpdateGisCacheInflux - Creates and initialize an Influx DB for a GIS Cache instance func (gc *GisCache) UpdateGisCacheInflux(sandboxName string, scenarioName string, influxAddr string) (err error) { - // Connect to Influx DB - for retry := 0; gc.influxClient == nil && retry <= dbMaxRetryCount; retry++ { - gc.influxClient, err = gc.connectInfluxDB(influxAddr) - if err != nil { - log.Warn("Failed to connect to InfluxDB. Retrying... Error: ", err) - } - } - if err != nil { - return err - } - log.Info("Connected to GIS Cache Influx DB") - - influxName := sandboxName - if scenarioName != "" { - influxName = influxName + "_" + scenarioName - } - - gc.influxName = strings.Replace(influxName, "-", "_", -1) - - err = gc.CreateInfluxDb() + // Connect to Influx DB + for retry := 0; gc.influxClient == nil && retry <= dbMaxRetryCount; retry++ { + gc.influxClient, err = gc.connectInfluxDB(influxAddr) + if err != nil { + log.Warn("Failed to connect to InfluxDB. Retrying... Error: ", err) + } + } + if err != nil { + return err + } + log.Info("Connected to GIS Cache Influx DB") + + influxName := sandboxName + if scenarioName != "" { + influxName = influxName + "_" + scenarioName + } + + gc.influxName = strings.Replace(influxName, "-", "_", -1) + + err = gc.CreateInfluxDb() if err != nil { log.Info("Error in creating influx db") } @@ -217,19 +218,19 @@ func (gc *GisCache) DelPosition(typ string, name string) { } // SetMeasurement - Create or update entry in DB -func (gc *GisCache) SetMeasurement(ue string, poaType string, poa string, meas *Measurement) error { - key := gc.baseKey + measKey + ue + ":" + poa +func (gc *GisCache) SetMeasurement(src string, srcType string, dest string, destType string, meas *Measurement) error { + key := gc.baseKey + measKey + src + ":" + dest // Prepare data fields := make(map[string]interface{}) - fields[fieldSrc] = fmt.Sprintf("%s", ue) - fields[fieldPoa] = fmt.Sprintf("%s", poa) - fields[fieldPoaType] = fmt.Sprintf("%s", poaType) + fields[fieldSrc] = fmt.Sprintf("%s", src) + fields[fieldSrcType] = fmt.Sprintf("%s", srcType) + fields[fieldDest] = fmt.Sprintf("%s", dest) + fields[fieldDestType] = fmt.Sprintf("%s", destType) fields[fieldRssi] = fmt.Sprintf("%f", meas.Rssi) fields[fieldRsrp] = fmt.Sprintf("%f", meas.Rsrp) fields[fieldRsrq] = fmt.Sprintf("%f", meas.Rsrq) - fields[fieldDistance] = fmt.Sprintf("%f", meas.Distance) - + fields[fieldDistance] = fmt.Sprintf("%f", meas.Distance) // Update entry in DB err := gc.rc.SetEntry(key, fields) @@ -284,10 +285,9 @@ func getMeasurement(key string, fields map[string]string, userData interface{}) if rsrq, err := strconv.ParseFloat(fields[fieldRsrq], 32); err == nil { meas.Rsrq = float32(rsrq) } - if distance, err := strconv.ParseFloat(fields[fieldDistance], 32); err == nil { - meas.Distance = float32(distance) - } - + if distance, err := strconv.ParseFloat(fields[fieldDistance], 32); err == nil { + meas.Distance = float32(distance) + } // Add measurement to map ueMeas, found := measurementMap[ueName] diff --git a/go-packages/meep-gis-cache/gis.go b/go-packages/meep-gis-cache/gis.go index d0b36152b..01377d496 100644 --- a/go-packages/meep-gis-cache/gis.go +++ b/go-packages/meep-gis-cache/gis.go @@ -28,12 +28,16 @@ import ( const UeMetName = "meas" const UeMetNameInflux = "gis" const UeMetSrc = "src" -const UeMetPoa = "poa" -const UeMetPoaType = "poatype" +const UeMetSrcType = "srcType" +const UeMetDest = "dest" +const UeMetDestType = "destType" +const UeMetMeasType = "measType" +const UeMetMeasTypeDistance = "distance" +const UeMetMeasTypeSignal = "signal" const UeMetRssi = "rssi" const UeMetRsrp = "rsrp" const UeMetRsrq = "rsrq" -const UeMetDistance = "distance" +const UeMetDistance = "dist" const UeMetTime = "time" type Metric struct { @@ -44,8 +48,9 @@ type Metric struct { type UeMetric struct { Src string - Poa string - PoaType string + SrcType string + Dest string + DestType string Time interface{} Rssi int32 Rsrp int32 @@ -173,15 +178,20 @@ func (gc *GisCache) formatCachedUeMetric(values map[string]interface{}) (metric } metric.Src = val.(string) - if val, ok = values[UeMetPoa]; !ok { + if val, ok = values[UeMetSrcType]; !ok { val = "" } - metric.Poa = val.(string) + metric.SrcType = val.(string) - if val, ok = values[UeMetPoaType]; !ok { + if val, ok = values[UeMetDest]; !ok { val = "" } - metric.PoaType = val.(string) + metric.Dest = val.(string) + + if val, ok = values[UeMetDestType]; !ok { + val = "" + } + metric.DestType = val.(string) if val, ok = values[UeMetRssi]; !ok { val = "" @@ -253,7 +263,8 @@ func (gc *GisCache) TakeUeMetricSnapshot() { // logTimeLapse("GetRedisMetric wildcard") // Prepare ue metrics list - metricList := make([]Metric, len(valuesArray)) + metricSignalList := make([]Metric, len(valuesArray)) + metricDistanceList := make([]Metric, len(valuesArray)) for index, values := range valuesArray { // Format network metric nm, err := gc.formatCachedUeMetric(values) @@ -262,19 +273,30 @@ func (gc *GisCache) TakeUeMetricSnapshot() { } // Add metric to list - metric := &metricList[index] - metric.Name = UeMetNameInflux - metric.Tags = map[string]string{UeMetSrc: nm.Src, UeMetPoa: nm.Poa, UeMetPoaType: nm.PoaType} - metric.Fields = map[string]interface{}{ - UeMetRssi: nm.Rssi, - UeMetRsrp: nm.Rsrp, - UeMetRsrq: nm.Rsrq, + metricSignal := &metricSignalList[index] + metricSignal.Name = UeMetNameInflux + metricSignal.Tags = map[string]string{UeMetSrc: nm.Src, UeMetSrcType: nm.SrcType, UeMetDest: nm.Dest, UeMetDestType: nm.DestType, UeMetMeasType: UeMetMeasTypeSignal} + metricSignal.Fields = map[string]interface{}{ + UeMetRssi: nm.Rssi, + UeMetRsrp: nm.Rsrp, + UeMetRsrq: nm.Rsrq, + } + metricDistance := &metricDistanceList[index] + metricDistance.Name = UeMetNameInflux + metricDistance.Tags = map[string]string{UeMetSrc: nm.Src, UeMetSrcType: nm.SrcType, UeMetDest: nm.Dest, UeMetDestType: nm.DestType, UeMetMeasType: UeMetMeasTypeDistance} + metricDistance.Fields = map[string]interface{}{ UeMetDistance: nm.Distance, } + } // Store metrics in influx - err = gc.SetInfluxMetric(metricList) + err = gc.SetInfluxMetric(metricSignalList) + if err != nil { + log.Error("Fail to write influx metrics with error: ", err.Error()) + } + // Store metrics in influx + err = gc.SetInfluxMetric(metricDistanceList) if err != nil { log.Error("Fail to write influx metrics with error: ", err.Error()) } @@ -285,35 +307,35 @@ func (gc *GisCache) TakeUeMetricSnapshot() { // CreateInfluxDb - func (gc *GisCache) CreateInfluxDb() error { - if gc.influxName != "" { - - // Create new DB if necessary - if gc.influxClient != nil { - q := influx.NewQuery("CREATE DATABASE "+ gc.influxName, "", "") - _, err := (*gc.influxClient).Query(q) - if err != nil { - log.Error("Query failed with error: ", err.Error()) - return err - } - } - } else { + if gc.influxName != "" { + + // Create new DB if necessary + if gc.influxClient != nil { + q := influx.NewQuery("CREATE DATABASE "+gc.influxName, "", "") + _, err := (*gc.influxClient).Query(q) + if err != nil { + log.Error("Query failed with error: ", err.Error()) + return err + } + } + } else { log.Error("Nil influxDbName") } log.Info("Influx database ", gc.influxName, " created") - return nil + return nil } // FlushInfluxDb - func (gc *GisCache) FlushInfluxDb() { - // Flush Influx DB - if gc.influxClient != nil { - q := influx.NewQuery("DROP SERIES FROM /.*/", gc.influxName, "") - response, err := (*gc.influxClient).Query(q) - if err != nil { - log.Error("Query failed with error: ", err.Error()) - } - log.Info(response.Results) - } + // Flush Influx DB + if gc.influxClient != nil { + q := influx.NewQuery("DROP SERIES FROM /.*/", gc.influxName, "") + response, err := (*gc.influxClient).Query(q) + if err != nil { + log.Error("Query failed with error: ", err.Error()) + } + log.Info(response.Results) + } } -- GitLab From 0c9581705ecbb49c4938ca8e0f6d789397623da3 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Mon, 17 May 2021 16:01:45 -0400 Subject: [PATCH 011/170] advantedge dashboards for signals and distance --- .../wireless-metrics-aggregation.json | 915 ++++++++++++++ .../wireless-metrics-point-to-point.json | 1123 +++++++++++++++++ .../js/containers/exec/dashboard-container.js | 25 +- .../meep-frontend/src/js/meep-constants.js | 8 + .../src/js/util/scenario-utils.js | 19 +- 5 files changed, 2082 insertions(+), 8 deletions(-) create mode 100644 charts/grafana/dashboards/wireless-metrics-aggregation.json create mode 100644 charts/grafana/dashboards/wireless-metrics-point-to-point.json diff --git a/charts/grafana/dashboards/wireless-metrics-aggregation.json b/charts/grafana/dashboards/wireless-metrics-aggregation.json new file mode 100644 index 000000000..a0c43ce3c --- /dev/null +++ b/charts/grafana/dashboards/wireless-metrics-aggregation.json @@ -0,0 +1,915 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "#3274D9", + "limit": 100, + "name": "Mobility Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='MOBILITY' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type", + "textColumn": "", + "type": "dashboard" + }, + { + "builtIn": 1, + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "#FF780A", + "name": "Net Char Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='NETWORK-CHARACTERISTICS-UPDATE' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type", + "textColumn": "", + "type": "dashboard" + }, + { + "builtIn": 1, + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "#A352CC", + "name": "PDU Session Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='PDU-SESSION' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type", + "textColumn": "", + "type": "dashboard" + }, + { + "builtIn": 1, + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "#E02F44", + "name": "Scenario Update Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='SCENARIO-UPDATE' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type", + "textColumn": "", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 23, + "iteration": 1621267088775, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 18, + "panels": [], + "title": "Signals Aggregation", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Shows RSRPs between source physical location & destination network locations", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 1, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "[[tag_dest]]", + "groupBy": [ + { + "params": [ + "1s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "measurement": "/^$scenario$/", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT rsrp FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RSRPs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Signal (Mapping)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "Throughput (Mbps)", + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Shows RSRQs between source physical location & destination network locations", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 1, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 26, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "[[tag_dest]]", + "groupBy": [ + { + "params": [ + "1s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "measurement": "/^$scenario$/", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT rsrq FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RSRQs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Signal (Mapping)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "Throughput (Mbps)", + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Shows RSSIs between source physical location & destination network locations", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 1, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 24, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "[[tag_dest]]", + "groupBy": [ + { + "params": [ + "1s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "measurement": "/^$scenario$/", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT rssi FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RSSIs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Signal (Mapping)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "Throughput (Mbps)", + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 20, + "panels": [], + "title": "Distance Aggregation", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Shows distances between source physical location & destination network locations", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 1, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 28, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "[[tag_dest]]", + "groupBy": [ + { + "params": [ + "1s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "measurement": "/^$scenario$/", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT dist FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Distances", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Distance (Meters)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "Throughput (Mbps)", + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 22, + "panels": [], + "title": "Events", + "type": "row" + }, + { + "cacheTimeout": null, + "columns": [], + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "100%", + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 43 + }, + "id": 4, + "links": [], + "pageSize": null, + "pluginVersion": "6.4.2", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "Type", + "align": "auto", + "colorMode": null, + "colors": [ + "#C4162A", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "events.type", + "thresholds": [], + "type": "string", + "unit": "short", + "valueMaps": [ + { + "text": "Net Char", + "value": "NETWORK-CHARACTERISTICS-UPDATE" + }, + { + "text": "Mobility", + "value": "MOBILITY" + }, + { + "text": "PDU Session", + "value": "PDU-SESSION" + }, + { + "text": "Scenario", + "value": "SCENARIO-UPDATE" + } + ] + }, + { + "alias": "Description", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "mappingType": 1, + "pattern": "events.description", + "thresholds": [], + "type": "string", + "unit": "short", + "valueMaps": [] + } + ], + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "events", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT type,description FROM $database.autogen.events WHERE $timeFilter ORDER BY time desc LIMIT 100", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "event" + ], + "type": "field" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Events", + "transform": "timeseries_to_columns", + "type": "table-old" + } + ], + "refresh": "", + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "meep-influxdb", + "value": "meep-influxdb" + }, + "error": null, + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "datasource", + "options": [], + "query": "influxdb", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "may14_4g_5g_wifi_macro", + "value": "may14_4g_5g_wifi_macro" + }, + "datasource": "$datasource", + "definition": "show databases", + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "database", + "options": [], + "query": "show databases", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "10.100.0.4", + "value": "10.100.0.4" + }, + "datasource": "$datasource", + "definition": "", + "error": null, + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "src", + "options": [], + "query": "show tag values on $database from gis with key = \"src\"", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1m", + "to": "now" + }, + "timepicker": { + "hidden": false, + "refresh_intervals": [ + "1s", + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Wireless Metrics Aggregation", + "uid": "6", + "version": 4 +} diff --git a/charts/grafana/dashboards/wireless-metrics-point-to-point.json b/charts/grafana/dashboards/wireless-metrics-point-to-point.json new file mode 100644 index 000000000..82914fa78 --- /dev/null +++ b/charts/grafana/dashboards/wireless-metrics-point-to-point.json @@ -0,0 +1,1123 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Mobility Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='MOBILITY' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type", + "textColumn": "", + "type": "dashboard" + }, + { + "datasource": "$datasource", + "enable": true, + "hide": false, + "iconColor": "#FF9830", + "name": "Net Char Events", + "query": "SELECT type,description from $database.autogen.events WHERE type='NETWORK-CHARACTERISTICS-UPDATE' AND $timeFilter ORDER BY time ASC LIMIT 100", + "showIn": 0, + "tagsColumn": "type" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 21, + "iteration": 1621266422427, + "links": [], + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 15, + "x": 0, + "y": 0 + }, + "id": 14, + "options": { + "content": "\n\n", + "mode": "markdown" + }, + "pluginVersion": "7.3.5", + "timeFrom": null, + "timeShift": null, + "title": "Signals", + "type": "text" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#F2495C" + ], + "datasource": "$datasource", + "decimals": 2, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 9, + "x": 15, + "y": 0 + }, + "id": 9, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.5.2", + "postfix": " m", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT \"dist\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Distance", + "type": "singlestat", + "valueFontSize": "100%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#F2495C" + ], + "datasource": "$datasource", + "decimals": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 5, + "x": 0, + "y": 1 + }, + "id": 8, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.5.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT \"rsrp\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "RSRP", + "type": "singlestat", + "valueFontSize": "100%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#F2495C" + ], + "datasource": "$datasource", + "decimals": 0, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 5, + "x": 5, + "y": 1 + }, + "id": 10, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.5.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT \"rsrq\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "RSRQ", + "type": "singlestat", + "valueFontSize": "100%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#F2495C" + ], + "datasource": "$datasource", + "decimals": 0, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 5, + "x": 10, + "y": 1 + }, + "id": 16, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.5.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT \"rssi\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "RSSI", + "type": "singlestat", + "valueFontSize": "100%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Shows RSRP, RSRQ, RSSI & DIstance between source physical location & destination network location", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 4, + "gridPos": { + "h": 11, + "w": 24, + "x": 0, + "y": 4 + }, + "hiddenSeries": false, + "id": 2, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "RSRP", + "groupBy": [ + { + "params": [ + "1s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "/^$scenario$/", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"rsrp\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "lat" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + }, + { + "alias": "RSRQ", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"rsrq\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "ul" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + }, + { + "alias": "RSSI", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"rssi\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", + "rawQuery": true, + "refId": "C", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "dl" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] + }, + { + "alias": "Distance", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"dist\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", + "rawQuery": true, + "refId": "D", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RSRP, RSRQ, RSSI & Distance", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Signal (Mapping)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "Distance (Meters)", + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "columns": [], + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "100%", + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 4, + "links": [], + "pageSize": null, + "pluginVersion": "6.4.2", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "Type", + "align": "auto", + "colorMode": null, + "colors": [ + "#C4162A", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "events.type", + "thresholds": [], + "type": "string", + "unit": "short", + "valueMaps": [ + { + "text": "Net Char", + "value": "NETWORK-CHARACTERISTICS-UPDATE" + }, + { + "text": "Mobility", + "value": "MOBILITY" + } + ] + }, + { + "alias": "Description", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "mappingType": 1, + "pattern": "events.description", + "thresholds": [], + "type": "string", + "unit": "short", + "valueMaps": [] + } + ], + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "events", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT type,description FROM $database.autogen.events WHERE $timeFilter ORDER BY time desc LIMIT 100", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "event" + ], + "type": "field" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Events", + "transform": "timeseries_to_columns", + "type": "table-old" + } + ], + "refresh": "5s", + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "meep-influxdb", + "value": "meep-influxdb" + }, + "error": null, + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "datasource", + "options": [], + "query": "influxdb", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "demo1", + "value": "demo1" + }, + "datasource": "$datasource", + "definition": "show databases", + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "database", + "options": [], + "query": "show databases", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "isNone": true, + "selected": false, + "text": "None", + "value": "" + }, + "datasource": "$datasource", + "definition": "", + "error": null, + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "src", + "options": [], + "query": "show tag values on $database from gis with key = \"src\"", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "isNone": true, + "selected": false, + "text": "None", + "value": "" + }, + "datasource": "$datasource", + "definition": "", + "error": null, + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "dest", + "options": [], + "query": "show tag values on $database from gis with key = \"dest\"", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1m", + "to": "now" + }, + "timepicker": { + "hidden": false, + "refresh_intervals": [ + "1s", + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Wireless Metrics Point-to-Point", + "uid": "5", + "version": 6 +} diff --git a/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js b/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js index 0d53ba21c..cd0b0471f 100644 --- a/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js +++ b/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js @@ -29,7 +29,7 @@ import IDCMap from '../idc-map'; import IDCVis from '../idc-vis'; import Iframe from 'react-iframe'; -import { getScenarioNodeChildren, isApp } from '../../util/scenario-utils'; +import { getScenarioNodeChildren, isApp, isUe, isPoa } from '../../util/scenario-utils'; import { uiExecChangeDashboardView1, @@ -93,7 +93,7 @@ const ConfigurationView = props => { { props.changeSourceNodeSelected(e.target.value); }} @@ -104,7 +104,7 @@ const ConfigurationView = props => { { props.changeDestNodeSelected(e.target.value); }} @@ -228,7 +228,8 @@ const DashboardConfiguration = props => { view2Name={props.view2Name} changeView1={props.changeView1} changeView2={props.changeView2} - nodeIds={props.nodeIds} + srcIds={props.srcIds} + destIds={props.destIds} sourceNodeSelected={props.sourceNodeSelected} destNodeSelected={props.destNodeSelected} changeSourceNodeSelected={props.changeSourceNodeSelected} @@ -356,10 +357,19 @@ class DashboardContainer extends Component { const nodes = root.descendants(); const apps = nodes.filter(isApp); const appIds = apps.map(a => a.data.name); + const ues = nodes.filter(isUe); + const ueIds = ues.map(a => a.data.name); + const poas = nodes.filter(isPoa); + const poaIds = poas.map(a => a.data.name); + const srcIds = appIds.concat(ueIds).sort(); + const destIds = appIds.concat(poaIds).sort(); + appIds.unshift('None'); + srcIds.unshift('None'); + destIds.unshift('None'); - const selectedSource = appIds.includes(this.props.sourceNodeSelected) ? this.props.sourceNodeSelected : 'None'; - const selectedDest = appIds.includes(this.props.destNodeSelected) ? this.props.destNodeSelected : 'None'; + const selectedSource = srcIds.includes(this.props.sourceNodeSelected) ? this.props.sourceNodeSelected : 'None'; + const selectedDest = destIds.includes(this.props.destNodeSelected) ? this.props.destNodeSelected : 'None'; const view1Name = this.getView1(); const view2Name = this.getView2(); const view1Present = view1Name !== VIEW_NAME_NONE; @@ -411,7 +421,8 @@ class DashboardContainer extends Component { ' + }, + { + label: 'Wireless Metrics Aggregation', + value: HOST_PATH + '/grafana/d/6/metrics-dashboard?orgId=1&var-datasource=meep-influxdb&refresh=1s&theme=light' + }, { label: 'Platform Metrics', value: HOST_PATH + '/grafana/d/platform-advantedge/platform-advantedge?orgId=1&refresh=15s&kiosk=tv&theme=light' diff --git a/js-apps/meep-frontend/src/js/util/scenario-utils.js b/js-apps/meep-frontend/src/js/util/scenario-utils.js index 1be904e0f..dbf082339 100644 --- a/js-apps/meep-frontend/src/js/util/scenario-utils.js +++ b/js-apps/meep-frontend/src/js/util/scenario-utils.js @@ -2162,6 +2162,23 @@ export const isApp = node => { ); }; +export const isUe = node => { + return ( + node.data.type && + node.data.type === 'UE' + ); +}; + +export const isPoa = node => { + return ( + node.data.type && + (node.data.type === 'POA-4G' || + node.data.type === 'POA-5G' || + node.data.type === 'POA-WIFI' || + node.data.type === 'POA') + ); +}; + export const getElementNames = (neType, scenario) => { var elementNames = []; for (var dInd in scenario.deployment.domains) { @@ -2184,4 +2201,4 @@ export const getElementNames = (neType, scenario) => { } return elementNames; -}; \ No newline at end of file +}; -- GitLab From 5c2f24c708817b37da62c830a35115d4d2a87f68 Mon Sep 17 00:00:00 2001 From: Nikhil Doifode Date: Wed, 19 May 2021 12:19:28 -0400 Subject: [PATCH 012/170] Codecoverage enabled for core and sandbox pods --- .meepctl-repocfg.yaml | 16 ++--- .../meep-gis-engine/templates/codecov-pv.yaml | 2 +- charts/meep-gis-engine/values-template.yaml | 1 + .../meep-loc-serv/templates/codecov-pv.yaml | 2 +- charts/meep-loc-serv/values-template.yaml | 1 + .../templates/codecov-pv.yaml | 2 +- .../meep-metrics-engine/values-template.yaml | 1 + .../meep-mg-manager/templates/codecov-pv.yaml | 2 +- charts/meep-mg-manager/values-template.yaml | 1 + .../meep-mon-engine/templates/codecov-pv.yaml | 2 +- charts/meep-mon-engine/values.yaml | 1 + charts/meep-rnis/templates/codecov-pv.yaml | 2 +- charts/meep-rnis/values-template.yaml | 1 + .../templates/codecov-pv.yaml | 2 +- charts/meep-sandbox-ctrl/values-template.yaml | 1 + .../meep-tc-engine/templates/codecov-pv.yaml | 2 +- charts/meep-tc-engine/values-template.yaml | 1 + .../templates/codecov-pv.yaml | 2 +- charts/meep-virt-engine/values.yaml | 1 + charts/meep-wais/templates/codecov-pv.yaml | 2 +- charts/meep-wais/values-template.yaml | 1 + go-apps/meep-rnis/main_test.go | 58 +++++++++++++++++++ go-apps/meep-virt-engine/helm/install.go | 6 +- go-apps/meep-wais/main_test.go | 58 +++++++++++++++++++ go-apps/meepctl/cmd/deploy.go | 2 + 25 files changed, 151 insertions(+), 19 deletions(-) create mode 100644 go-apps/meep-rnis/main_test.go create mode 100644 go-apps/meep-wais/main_test.go diff --git a/.meepctl-repocfg.yaml b/.meepctl-repocfg.yaml index d3476ce92..51f9b7340 100644 --- a/.meepctl-repocfg.yaml +++ b/.meepctl-repocfg.yaml @@ -393,7 +393,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -417,7 +417,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -441,7 +441,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -462,7 +462,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -486,7 +486,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -510,7 +510,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -531,7 +531,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true # location of API specification @@ -555,7 +555,7 @@ repo: # enable meepctl deploy/delete deploy: true # supports code coverage measurement when built in codecov mode - codecov: false + codecov: true # supports linting lint: true meep-tc-sidecar: diff --git a/charts/meep-gis-engine/templates/codecov-pv.yaml b/charts/meep-gis-engine/templates/codecov-pv.yaml index 2f78d0b60..361cc3449 100644 --- a/charts/meep-gis-engine/templates/codecov-pv.yaml +++ b/charts/meep-gis-engine/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-gis-engine" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-gis-engine/values-template.yaml b/charts/meep-gis-engine/values-template.yaml index ca5edb526..ff9700f2c 100644 --- a/charts/meep-gis-engine/values-template.yaml +++ b/charts/meep-gis-engine/values-template.yaml @@ -50,6 +50,7 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-gis-engine" meepOrigin: core diff --git a/charts/meep-loc-serv/templates/codecov-pv.yaml b/charts/meep-loc-serv/templates/codecov-pv.yaml index 474bff5f1..6cbcfb641 100644 --- a/charts/meep-loc-serv/templates/codecov-pv.yaml +++ b/charts/meep-loc-serv/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-loc-serv" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-loc-serv/values-template.yaml b/charts/meep-loc-serv/values-template.yaml index ef3412f27..da1063394 100644 --- a/charts/meep-loc-serv/values-template.yaml +++ b/charts/meep-loc-serv/values-template.yaml @@ -51,5 +51,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-loc-serv" meepOrigin: core diff --git a/charts/meep-metrics-engine/templates/codecov-pv.yaml b/charts/meep-metrics-engine/templates/codecov-pv.yaml index 1c8c6a7d9..03a5f496f 100644 --- a/charts/meep-metrics-engine/templates/codecov-pv.yaml +++ b/charts/meep-metrics-engine/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-metrics-engine" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-metrics-engine/values-template.yaml b/charts/meep-metrics-engine/values-template.yaml index 6561020a8..d89e66bfd 100644 --- a/charts/meep-metrics-engine/values-template.yaml +++ b/charts/meep-metrics-engine/values-template.yaml @@ -51,5 +51,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-metrics-engine" meepOrigin: core diff --git a/charts/meep-mg-manager/templates/codecov-pv.yaml b/charts/meep-mg-manager/templates/codecov-pv.yaml index 4689ca4ca..11396dcc0 100644 --- a/charts/meep-mg-manager/templates/codecov-pv.yaml +++ b/charts/meep-mg-manager/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-mg-manager" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-mg-manager/values-template.yaml b/charts/meep-mg-manager/values-template.yaml index a684ce6d3..b15765281 100644 --- a/charts/meep-mg-manager/values-template.yaml +++ b/charts/meep-mg-manager/values-template.yaml @@ -58,5 +58,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-mg-manager" meepOrigin: core diff --git a/charts/meep-mon-engine/templates/codecov-pv.yaml b/charts/meep-mon-engine/templates/codecov-pv.yaml index 3dc8532e0..0095aff17 100644 --- a/charts/meep-mon-engine/templates/codecov-pv.yaml +++ b/charts/meep-mon-engine/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-mon-engine" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-mon-engine/values.yaml b/charts/meep-mon-engine/values.yaml index 6091ed3be..ce8af13aa 100644 --- a/charts/meep-mon-engine/values.yaml +++ b/charts/meep-mon-engine/values.yaml @@ -54,5 +54,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-mon-engine" meepOrigin: core diff --git a/charts/meep-rnis/templates/codecov-pv.yaml b/charts/meep-rnis/templates/codecov-pv.yaml index 8e00d9b43..11150ceeb 100644 --- a/charts/meep-rnis/templates/codecov-pv.yaml +++ b/charts/meep-rnis/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-rnis" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-rnis/values-template.yaml b/charts/meep-rnis/values-template.yaml index b514ef997..79ccae166 100644 --- a/charts/meep-rnis/values-template.yaml +++ b/charts/meep-rnis/values-template.yaml @@ -53,5 +53,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-rnis" meepOrigin: core diff --git a/charts/meep-sandbox-ctrl/templates/codecov-pv.yaml b/charts/meep-sandbox-ctrl/templates/codecov-pv.yaml index 5b879ffe8..052357bac 100644 --- a/charts/meep-sandbox-ctrl/templates/codecov-pv.yaml +++ b/charts/meep-sandbox-ctrl/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-sandbox-ctrl" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-sandbox-ctrl/values-template.yaml b/charts/meep-sandbox-ctrl/values-template.yaml index 5f49db0a7..013169f1d 100644 --- a/charts/meep-sandbox-ctrl/values-template.yaml +++ b/charts/meep-sandbox-ctrl/values-template.yaml @@ -72,5 +72,6 @@ user: servepath: "/user-swagger-sandbox" codecov: enabled: false + location: "/codecov/meep-sandbox-ctrl" meepOrigin: core diff --git a/charts/meep-tc-engine/templates/codecov-pv.yaml b/charts/meep-tc-engine/templates/codecov-pv.yaml index b54b4aedd..97dbf28e8 100644 --- a/charts/meep-tc-engine/templates/codecov-pv.yaml +++ b/charts/meep-tc-engine/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-tc-engine" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-tc-engine/values-template.yaml b/charts/meep-tc-engine/values-template.yaml index 96e1d24fd..61cf5cc9d 100644 --- a/charts/meep-tc-engine/values-template.yaml +++ b/charts/meep-tc-engine/values-template.yaml @@ -32,5 +32,6 @@ service: codecov: enabled: false + location: "/codecov/meep-tc-engine" meepOrigin: core diff --git a/charts/meep-virt-engine/templates/codecov-pv.yaml b/charts/meep-virt-engine/templates/codecov-pv.yaml index 82a94ad5b..e22f620ea 100644 --- a/charts/meep-virt-engine/templates/codecov-pv.yaml +++ b/charts/meep-virt-engine/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-virt-engine" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-virt-engine/values.yaml b/charts/meep-virt-engine/values.yaml index 297ac0133..77c188a61 100644 --- a/charts/meep-virt-engine/values.yaml +++ b/charts/meep-virt-engine/values.yaml @@ -61,5 +61,6 @@ user: codecov: enabled: false + location: "/codecov/meep-virt-engine" meepOrigin: core diff --git a/charts/meep-wais/templates/codecov-pv.yaml b/charts/meep-wais/templates/codecov-pv.yaml index 5311dfd36..5935763ac 100644 --- a/charts/meep-wais/templates/codecov-pv.yaml +++ b/charts/meep-wais/templates/codecov-pv.yaml @@ -11,7 +11,7 @@ spec: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: - path: "/home/englab/.meep/codecov/meep-wais" + path: {{ .Values.codecov.location }} --- kind: StorageClass diff --git a/charts/meep-wais/values-template.yaml b/charts/meep-wais/values-template.yaml index 287a86659..02bdf56fd 100644 --- a/charts/meep-wais/values-template.yaml +++ b/charts/meep-wais/values-template.yaml @@ -51,5 +51,6 @@ prometheus: codecov: enabled: false + location: "/codecov/meep-wais" meepOrigin: core diff --git a/go-apps/meep-rnis/main_test.go b/go-apps/meep-rnis/main_test.go new file mode 100644 index 000000000..7f017cfd4 --- /dev/null +++ b/go-apps/meep-rnis/main_test.go @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 InterDigital Communications, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "os" + "strings" + "testing" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" +) + +// Build: +// $ go test -covermode=count -coverpkg=./... -c -o +// Run: +// $ ./ -test.coverprofile=cover.out __DEVEL--code-cov + +// TestMain is a hack that allows us to figure out what the coverage is during +// integration tests. I would not recommend that you use a binary built using +// this hack outside of a test suite. +func TestMain(t *testing.T) { + var ( + args []string + run bool + ) + + log.Info(os.Args) + for _, arg := range os.Args { + switch { + case arg == "__DEVEL--code-cov": + run = true + case strings.HasPrefix(arg, "-test"): + case strings.HasPrefix(arg, "__DEVEL"): + default: + args = append(args, arg) + } + } + os.Args = args + log.Info(os.Args) + + if run { + main() + } +} diff --git a/go-apps/meep-virt-engine/helm/install.go b/go-apps/meep-virt-engine/helm/install.go index f58b5ce47..51639e111 100644 --- a/go-apps/meep-virt-engine/helm/install.go +++ b/go-apps/meep-virt-engine/helm/install.go @@ -18,6 +18,7 @@ package helm import ( "errors" + "os" "os/exec" "strings" @@ -61,11 +62,14 @@ func install(chart Chart) error { log.Debug("Installing chart: " + chart.ReleaseName) var cmd *exec.Cmd if strings.Trim(chart.ValuesFile, " ") == "" { + codecovLocation := strings.TrimSpace(os.Getenv("MEEP_CODECOV_LOCATION")) + chart.ReleaseName cmd = exec.Command("helm", "install", chart.ReleaseName, "--namespace", chart.Namespace, "--create-namespace", "--set", "nameOverride="+chart.Name, "--set", "fullnameOverride="+chart.Name, - chart.Location, "--replace", "--disable-openapi-validation") + chart.Location, "--replace", "--disable-openapi-validation", + "--set", "codecov.enabled="+strings.TrimSpace(os.Getenv("MEEP_CODECOV")), + "--set", "codecov.location="+codecovLocation) } else { cmd = exec.Command("helm", "install", chart.ReleaseName, "--namespace", chart.Namespace, "--create-namespace", diff --git a/go-apps/meep-wais/main_test.go b/go-apps/meep-wais/main_test.go new file mode 100644 index 000000000..7f017cfd4 --- /dev/null +++ b/go-apps/meep-wais/main_test.go @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 InterDigital Communications, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "os" + "strings" + "testing" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" +) + +// Build: +// $ go test -covermode=count -coverpkg=./... -c -o +// Run: +// $ ./ -test.coverprofile=cover.out __DEVEL--code-cov + +// TestMain is a hack that allows us to figure out what the coverage is during +// integration tests. I would not recommend that you use a binary built using +// this hack outside of a test suite. +func TestMain(t *testing.T) { + var ( + args []string + run bool + ) + + log.Info(os.Args) + for _, arg := range os.Args { + switch { + case arg == "__DEVEL--code-cov": + run = true + case strings.HasPrefix(arg, "-test"): + case strings.HasPrefix(arg, "__DEVEL"): + default: + args = append(args, arg) + } + } + os.Args = args + log.Info(os.Args) + + if run { + main() + } +} diff --git a/go-apps/meepctl/cmd/deploy.go b/go-apps/meepctl/cmd/deploy.go index 1048b0125..feccb1655 100644 --- a/go-apps/meepctl/cmd/deploy.go +++ b/go-apps/meepctl/cmd/deploy.go @@ -192,6 +192,8 @@ func deployCore(cobraCmd *cobra.Command) { coreFlags := utils.HelmFlags(flags, "--set", "image.repository="+deployData.registry+"/"+app) coreFlags = utils.HelmFlags(coreFlags, "--set", "image.tag="+deployData.tag) if deployData.codecov && codecov { + coreFlags = utils.HelmFlags(coreFlags, "--set", "image.env.MEEP_CODECOV='true'") + coreFlags = utils.HelmFlags(coreFlags, "--set", "image.env.MEEP_CODECOV_LOCATION="+deployData.workdir+"/codecov/") coreFlags = utils.HelmFlags(coreFlags, "--set", "codecov.enabled=true") coreFlags = utils.HelmFlags(coreFlags, "--set", "codecov.location="+deployData.workdir+"/codecov/"+app) } -- GitLab From 0658a7a42484f334278456fa5ace8e49816b2d28 Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Tue, 25 May 2021 11:53:39 -0400 Subject: [PATCH 013/170] grafana graph update --- .meepctl-repocfg.yaml | 2 + .../wireless-metrics-aggregation.json | 60 +++++++++++------- .../wireless-metrics-point-to-point.json | 61 +++++++++++++------ .../meep-sandbox-ctrl/server/sandbox-ctrl.go | 14 ++++- go-packages/meep-metrics/events.go | 16 ++++- 5 files changed, 112 insertions(+), 41 deletions(-) diff --git a/.meepctl-repocfg.yaml b/.meepctl-repocfg.yaml index d3476ce92..0ef6835b4 100644 --- a/.meepctl-repocfg.yaml +++ b/.meepctl-repocfg.yaml @@ -95,6 +95,8 @@ repo: dashboards: network-metrics-point-to-point: dashboards/network-metrics-point-to-point.json network-metrics-aggregation: dashboards/network-metrics-aggregation.json + wireless-metrics-point-to-point: dashboards/wireless-metrics-point-to-point.json + wireless-metrics-aggregation: dashboards/wireless-metrics-aggregation.json http-single-log: dashboards/http-log-byId.json http-logs-aggregation: dashboards/http-loggers.json platform-advantedge: dashboards/platform-advantedge.json diff --git a/charts/grafana/dashboards/wireless-metrics-aggregation.json b/charts/grafana/dashboards/wireless-metrics-aggregation.json index a0c43ce3c..361c08d5b 100644 --- a/charts/grafana/dashboards/wireless-metrics-aggregation.json +++ b/charts/grafana/dashboards/wireless-metrics-aggregation.json @@ -59,8 +59,7 @@ "editable": true, "gnetId": null, "graphTooltip": 0, - "id": 23, - "iteration": 1621267088775, + "iteration": 1621447328946, "links": [], "panels": [ { @@ -106,6 +105,8 @@ "legend": { "avg": false, "current": false, + "hideEmpty": false, + "hideZero": true, "max": false, "min": false, "show": true, @@ -115,7 +116,7 @@ "lines": true, "linewidth": 2, "links": [], - "nullPointMode": "connected", + "nullPointMode": "null", "options": { "alertThreshold": true }, @@ -149,7 +150,7 @@ "measurement": "/^$scenario$/", "orderByTime": "ASC", "policy": "default", - "query": "SELECT rsrp FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "query": "SELECT mean(\"rsrp\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest, time(1s)", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -186,7 +187,7 @@ "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "RSRPs", + "title": "RSRPs (4G / 5G)", "tooltip": { "shared": true, "sort": 0, @@ -252,6 +253,7 @@ "legend": { "avg": false, "current": false, + "hideZero": true, "max": false, "min": false, "show": true, @@ -261,7 +263,7 @@ "lines": true, "linewidth": 2, "links": [], - "nullPointMode": "connected", + "nullPointMode": "null", "options": { "alertThreshold": true }, @@ -295,7 +297,7 @@ "measurement": "/^$scenario$/", "orderByTime": "ASC", "policy": "default", - "query": "SELECT rsrq FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "query": "SELECT mean(\"rsrq\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest, time(1s)", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -332,7 +334,7 @@ "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "RSRQs", + "title": "RSRQs (4G / 5G)", "tooltip": { "shared": true, "sort": 0, @@ -398,6 +400,7 @@ "legend": { "avg": false, "current": false, + "hideZero": true, "max": false, "min": false, "show": true, @@ -407,7 +410,7 @@ "lines": true, "linewidth": 2, "links": [], - "nullPointMode": "connected", + "nullPointMode": "null", "options": { "alertThreshold": true }, @@ -441,7 +444,7 @@ "measurement": "/^$scenario$/", "orderByTime": "ASC", "policy": "default", - "query": "SELECT rssi FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "query": "SELECT mean(\"rssi\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest, time(1s)", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -478,7 +481,7 @@ "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "RSSIs", + "title": "RSSIs (WIFI)", "tooltip": { "shared": true, "sort": 0, @@ -558,6 +561,7 @@ "legend": { "avg": false, "current": false, + "hideZero": false, "max": false, "min": false, "show": true, @@ -567,7 +571,7 @@ "lines": true, "linewidth": 2, "links": [], - "nullPointMode": "connected", + "nullPointMode": "null", "options": { "alertThreshold": true }, @@ -601,7 +605,7 @@ "measurement": "/^$scenario$/", "orderByTime": "ASC", "policy": "default", - "query": "SELECT dist FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest", + "query": "SELECT mean(\"dist\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/) AND $timeFilter GROUP BY dest, time(1s)", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -783,7 +787,7 @@ "measurement": "events", "orderByTime": "ASC", "policy": "default", - "query": "SELECT type,description FROM $database.autogen.events WHERE $timeFilter ORDER BY time desc LIMIT 100", + "query": "SELECT type,description FROM $database.autogen.events WHERE $timeFilter AND (\"src\" =~ /^$src$/) ORDER BY time desc LIMIT 100", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -797,7 +801,19 @@ } ] ], - "tags": [] + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] } ], "timeFrom": null, @@ -807,7 +823,7 @@ "type": "table-old" } ], - "refresh": "", + "refresh": "1s", "schemaVersion": 26, "style": "dark", "tags": [], @@ -836,8 +852,8 @@ "allValue": null, "current": { "selected": false, - "text": "may14_4g_5g_wifi_macro", - "value": "may14_4g_5g_wifi_macro" + "text": "_internal", + "value": "_internal" }, "datasource": "$datasource", "definition": "show databases", @@ -862,9 +878,10 @@ { "allValue": null, "current": { + "isNone": true, "selected": false, - "text": "10.100.0.4", - "value": "10.100.0.4" + "text": "None", + "value": "" }, "datasource": "$datasource", "definition": "", @@ -911,5 +928,6 @@ "timezone": "", "title": "Wireless Metrics Aggregation", "uid": "6", - "version": 4 + "version": 6 } + diff --git a/charts/grafana/dashboards/wireless-metrics-point-to-point.json b/charts/grafana/dashboards/wireless-metrics-point-to-point.json index 82914fa78..29659f275 100644 --- a/charts/grafana/dashboards/wireless-metrics-point-to-point.json +++ b/charts/grafana/dashboards/wireless-metrics-point-to-point.json @@ -30,8 +30,7 @@ "editable": true, "gnetId": null, "graphTooltip": 0, - "id": 21, - "iteration": 1621266422427, + "iteration": 1621449565579, "links": [], "panels": [ { @@ -145,7 +144,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT \"dist\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", @@ -278,7 +277,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT \"rsrp\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", @@ -313,7 +312,7 @@ "thresholds": "", "timeFrom": null, "timeShift": null, - "title": "RSRP", + "title": "RSRP (4G / 5G)", "type": "singlestat", "valueFontSize": "100%", "valueMaps": [ @@ -411,7 +410,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT \"rsrq\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", @@ -446,7 +445,7 @@ "thresholds": "", "timeFrom": null, "timeShift": null, - "title": "RSRQ", + "title": "RSRQ (4G / 5G)", "type": "singlestat", "valueFontSize": "100%", "valueMaps": [ @@ -544,7 +543,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT \"rssi\" FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter", @@ -579,7 +578,7 @@ "thresholds": "", "timeFrom": null, "timeShift": null, - "title": "RSSI", + "title": "RSSI (WIFI)", "type": "singlestat", "valueFontSize": "100%", "valueMaps": [ @@ -620,6 +619,7 @@ "legend": { "avg": false, "current": false, + "hideZero": true, "max": false, "min": false, "show": true, @@ -629,7 +629,7 @@ "lines": true, "linewidth": 2, "links": [], - "nullPointMode": "connected", + "nullPointMode": "null", "options": { "alertThreshold": true }, @@ -659,7 +659,7 @@ "type": "fill" } ], - "measurement": "/^$scenario$/", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT mean(\"rsrp\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", @@ -710,7 +710,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT mean(\"rsrq\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", @@ -761,7 +761,7 @@ "type": "fill" } ], - "measurement": "network", + "measurement": "gis", "orderByTime": "ASC", "policy": "default", "query": "SELECT mean(\"rssi\") FROM $database.autogen.gis WHERE (\"src\" =~ /^$src$/ AND \"dest\" =~ /^$dest$/) AND $timeFilter GROUP BY time(1s)", @@ -832,7 +832,19 @@ } ] ], - "tags": [] + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] } ], "thresholds": [], @@ -962,7 +974,7 @@ "measurement": "events", "orderByTime": "ASC", "policy": "default", - "query": "SELECT type,description FROM $database.autogen.events WHERE $timeFilter ORDER BY time desc LIMIT 100", + "query": "SELECT type,description FROM $database.autogen.events WHERE (\"src\" =~ /^$src$/ AND (\"dest\" =~ /^$dest$/ OR \"dest\" = \'\')) AND $timeFilter ORDER BY time desc LIMIT 100", "rawQuery": true, "refId": "A", "resultFormat": "time_series", @@ -976,7 +988,19 @@ } ] ], - "tags": [] + "tags": [ + { + "key": "src", + "operator": "=~", + "value": "/^$src$/" + }, + { + "condition": "AND", + "key": "dest", + "operator": "=~", + "value": "/^$dest$/" + } + ] } ], "timeFrom": null, @@ -986,7 +1010,7 @@ "type": "table-old" } ], - "refresh": "5s", + "refresh": "1s", "schemaVersion": 26, "style": "dark", "tags": [], @@ -1119,5 +1143,6 @@ "timezone": "", "title": "Wireless Metrics Point-to-Point", "uid": "5", - "version": 6 + "version": 7 } + diff --git a/go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go b/go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go index 533555565..eb83e9e99 100644 --- a/go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go +++ b/go-apps/meep-sandbox-ctrl/server/sandbox-ctrl.go @@ -788,14 +788,24 @@ func ceSendEvent(w http.ResponseWriter, r *http.Request) { // Process Event var httpStatus int - var description string + var description, src, dest string switch eventType { case eventTypeMobility: err, httpStatus, description = sendEventMobility(event) + if err == nil { + src = event.EventMobility.ElementName + dest = event.EventMobility.Dest + } case eventTypeNetCharUpdate: err, httpStatus, description = sendEventNetworkCharacteristics(event) + if err == nil { + src = event.EventNetworkCharacteristicsUpdate.ElementName + } case eventTypePoasInRange: err, httpStatus, description = sendEventPoasInRange(event) + if err == nil { + src = event.EventPoasInRange.Ue + } case eventTypeScenarioUpdate: err, httpStatus, description = sendEventScenarioUpdate(event) case eventTypePduSession: @@ -817,6 +827,8 @@ func ceSendEvent(w http.ResponseWriter, r *http.Request) { var metric met.EventMetric metric.Event = string(eventJSONStr) metric.Description = description + metric.Src = src + metric.Dest = dest err = sbxCtrl.metricStore.SetEventMetric(eventType, metric) } if err != nil { diff --git a/go-packages/meep-metrics/events.go b/go-packages/meep-metrics/events.go index 57295a767..d8c63dea6 100644 --- a/go-packages/meep-metrics/events.go +++ b/go-packages/meep-metrics/events.go @@ -26,11 +26,15 @@ const EvMetName = "events" const EvMetType = "type" const EvMetEvent = "event" const EvMetDescription = "description" +const EvMetSrc = "src" +const EvMetDest = "dest" type EventMetric struct { Time interface{} Event string Description string + Src string + Dest string } // SetEventMetric @@ -38,7 +42,11 @@ func (ms *MetricStore) SetEventMetric(eventType string, em EventMetric) error { metricList := make([]Metric, 1) metric := &metricList[0] metric.Name = EvMetName - metric.Tags = map[string]string{EvMetType: eventType} + metric.Tags = map[string]string{ + EvMetType: eventType, + EvMetSrc: em.Src, + EvMetDest: em.Dest, + } metric.Fields = map[string]interface{}{ EvMetEvent: em.Event, EvMetDescription: em.Description, @@ -78,6 +86,12 @@ func (ms *MetricStore) GetEventMetric(eventType string, duration string, count i if val, ok := values[EvMetDescription].(string); ok { metrics[index].Description = val } + if val, ok := values[EvMetSrc].(string); ok { + metrics[index].Src = val + } + if val, ok := values[EvMetDest].(string); ok { + metrics[index].Dest = val + } } return } -- GitLab From 05ec3084e9ed0a871bbe2ec684cd302e1241254c Mon Sep 17 00:00:00 2001 From: Simon Pastor Date: Fri, 28 May 2021 09:06:32 -0400 Subject: [PATCH 014/170] dashboard integration with different sources and destinations --- .../js/containers/exec/dashboard-container.js | 182 +------- .../src/js/containers/exec/event-container.js | 9 +- .../js/containers/exec/exec-page-container.js | 38 +- .../exec/exec-page-scenario-buttons.js | 6 +- .../src/js/containers/exec/view-pane.js | 387 ++++++++++++++++++ .../js/containers/exec/view-specific-pane.js | 227 ++++++++++ .../meep-frontend/src/js/meep-constants.js | 9 + .../meep-frontend/src/js/state/ui/index.js | 78 +++- 8 files changed, 746 insertions(+), 190 deletions(-) create mode 100644 js-apps/meep-frontend/src/js/containers/exec/view-pane.js create mode 100644 js-apps/meep-frontend/src/js/containers/exec/view-specific-pane.js diff --git a/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js b/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js index cd0b0471f..7c1ab2e92 100644 --- a/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js +++ b/js-apps/meep-frontend/src/js/containers/exec/dashboard-container.js @@ -20,22 +20,14 @@ import autoBind from 'react-autobind'; import { Grid, GridCell } from '@rmwc/grid'; import { Elevation } from '@rmwc/elevation'; // import ReactDOM from 'react-dom'; -import { Button } from '@rmwc/button'; -import { Checkbox } from '@rmwc/checkbox'; -import * as d3 from 'd3'; -import IDSelect from '../../components/helper-components/id-select'; import IDCMap from '../idc-map'; import IDCVis from '../idc-vis'; import Iframe from 'react-iframe'; -import { getScenarioNodeChildren, isApp, isUe, isPoa } from '../../util/scenario-utils'; - import { uiExecChangeDashboardView1, uiExecChangeDashboardView2, - uiExecChangeSourceNodeSelected, - uiExecChangeDestNodeSelected, uiExecChangeSandboxCfg } from '../../state/ui'; @@ -44,8 +36,7 @@ import { VIEW_NAME_NONE, MAP_VIEW, NET_TOPOLOGY_VIEW, - DEFAULT_DASHBOARD_OPTIONS, - EXEC_BTN_DASHBOARD_BTN_CLOSE + DEFAULT_DASHBOARD_OPTIONS } from '../../meep-constants'; import { updateObject } from '../../util/object-util'; @@ -63,67 +54,6 @@ const styles = { const showInExecStr = ''; const passVarsStr = ''; -const ConfigurationView = props => { - return ( - <> - - - { - props.changeView1(e.target.value); - }} - value={props.view1Name} - /> - - - { - props.changeView2(e.target.value); - }} - value={props.view2Name} - /> - - - { - props.changeSourceNodeSelected(e.target.value); - }} - value={props.sourceNodeSelected} - /> - - - { - props.changeDestNodeSelected(e.target.value); - }} - value={props.destNodeSelected} - /> - - - props.changeShowApps(e.target.checked)} - > - Show Apps - - - - - ); -}; - const getUrl = (dashboardName, dashboardOptions) => { var url = ''; if (dashboardOptions) { @@ -214,62 +144,6 @@ const ViewForName = ({ return null; }; -const DashboardConfiguration = props => { - if (!props.dashCfgMode) { - return null; - } - - let configurationView = null; - - configurationView = ( - - ); - return ( - - - -
- - Dashboard - -
-
- -
- -
-
-
- {configurationView} -
- ); -}; - class DashboardContainer extends Component { constructor(props) { super(props); @@ -302,10 +176,6 @@ class DashboardContainer extends Component { } } - getRoot() { - return d3.hierarchy(this.props.displayedScenario, getScenarioNodeChildren); - } - changeShowApps(checked) { this.props.onShowAppsChanged(checked); } @@ -353,23 +223,7 @@ class DashboardContainer extends Component { render() { this.keyForSvg++; - const root = this.getRoot(); - const nodes = root.descendants(); - const apps = nodes.filter(isApp); - const appIds = apps.map(a => a.data.name); - const ues = nodes.filter(isUe); - const ueIds = ues.map(a => a.data.name); - const poas = nodes.filter(isPoa); - const poaIds = poas.map(a => a.data.name); - const srcIds = appIds.concat(ueIds).sort(); - const destIds = appIds.concat(poaIds).sort(); - - appIds.unshift('None'); - srcIds.unshift('None'); - destIds.unshift('None'); - - const selectedSource = srcIds.includes(this.props.sourceNodeSelected) ? this.props.sourceNodeSelected : 'None'; - const selectedDest = destIds.includes(this.props.destNodeSelected) ? this.props.destNodeSelected : 'None'; + const view1Name = this.getView1(); const view2Name = this.getView2(); const view1Present = view1Name !== VIEW_NAME_NONE; @@ -389,8 +243,8 @@ class DashboardContainer extends Component { @@ -400,8 +254,8 @@ class DashboardContainer extends Component { @@ -418,24 +272,6 @@ class DashboardContainer extends Component { return ( <> - - {!view1Present ? null : ( @@ -475,6 +311,10 @@ const mapStateToProps = state => { displayedScenario: state.exec.displayedScenario, sourceNodeSelected: state.ui.sourceNodeSelected, destNodeSelected: state.ui.destNodeSelected, + sourceNodeSelectedView1: state.ui.sourceNodeSelectedView1, + destNodeSelectedView1: state.ui.destNodeSelectedView1, + sourceNodeSelectedView2: state.ui.sourceNodeSelectedView2, + destNodeSelectedView2: state.ui.destNodeSelectedView2, eventCreationMode: state.exec.eventCreationMode, scenarioState: state.exec.state.scenario, view1Name: state.ui.dashboardView1, @@ -486,8 +326,6 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { - changeSourceNodeSelected: src => dispatch(uiExecChangeSourceNodeSelected(src)), - changeDestNodeSelected: dest => dispatch(uiExecChangeDestNodeSelected(dest)), changeView1: name => dispatch(uiExecChangeDashboardView1(name)), changeView2: name => dispatch(uiExecChangeDashboardView2(name)), changeSandboxCfg: cfg => dispatch(uiExecChangeSandboxCfg(cfg)) diff --git a/js-apps/meep-frontend/src/js/containers/exec/event-container.js b/js-apps/meep-frontend/src/js/containers/exec/event-container.js index e0486479b..66a9fed33 100644 --- a/js-apps/meep-frontend/src/js/containers/exec/event-container.js +++ b/js-apps/meep-frontend/src/js/containers/exec/event-container.js @@ -24,7 +24,8 @@ import { Typography } from '@rmwc/typography'; import { uiExecChangeEventCreationMode, uiExecChangeEventAutomationMode, - uiExecChangeEventReplayMode + uiExecChangeEventReplayMode, + uiExecChangeViewMode } from '../../state/ui'; import { @@ -91,6 +92,7 @@ class EventContainer extends Component { this.props.changeEventCreationMode(true); this.props.changeEventAutomationMode(false); this.props.changeEventReplayMode(false); + this.props.changeViewMode(false); } // EVENT AUTOMATION PANE @@ -98,6 +100,7 @@ class EventContainer extends Component { this.props.changeEventCreationMode(false); this.props.changeEventAutomationMode(true); this.props.changeEventReplayMode(false); + this.props.changeViewMode(false); } // SHOW REPLAY EVENT PANE @@ -105,6 +108,7 @@ class EventContainer extends Component { this.props.changeEventCreationMode(false); this.props.changeEventAutomationMode(false); this.props.changeEventReplayMode(true); + this.props.changeViewMode(false); // Refresh this.props.onShowReplay(); @@ -211,7 +215,8 @@ const mapDispatchToProps = dispatch => { return { changeEventCreationMode: mode => dispatch(uiExecChangeEventCreationMode(mode)), changeEventAutomationMode: mode => dispatch(uiExecChangeEventAutomationMode(mode)), - changeEventReplayMode: mode => dispatch(uiExecChangeEventReplayMode(mode)) + changeEventReplayMode: mode => dispatch(uiExecChangeEventReplayMode(mode)), + changeViewMode: mode => dispatch(uiExecChangeViewMode(mode)) }; }; diff --git a/js-apps/meep-frontend/src/js/containers/exec/exec-page-container.js b/js-apps/meep-frontend/src/js/containers/exec/exec-page-container.js index 6330074ba..af799dc9a 100644 --- a/js-apps/meep-frontend/src/js/containers/exec/exec-page-container.js +++ b/js-apps/meep-frontend/src/js/containers/exec/exec-page-container.js @@ -30,6 +30,7 @@ import HeadlineBar from '../../components/headline-bar'; import EventCreationPane from './event-creation-pane'; import EventAutomationPane from './event-automation-pane'; import EventReplayPane from './event-replay-pane'; +import ViewPane from './view-pane'; import ExecTable from './exec-table'; @@ -46,6 +47,7 @@ import { execChangeScenarioList} from '../../state/exec'; import { uiChangeCurrentDialog, uiExecChangeEventCreationMode, + uiExecChangeViewMode, uiExecChangeEventAutomationMode, uiExecChangeEventReplayMode, uiExecChangeDashCfgMode, @@ -74,6 +76,8 @@ import { NETWORK_CHARACTERISTICS_EVENT, SCENARIO_UPDATE_EVENT, PDU_SESSION_EVENT, + VIEW_1, + VIEW_2, EXEC_SELECT_SANDBOX } from '../../meep-constants'; @@ -212,6 +216,7 @@ class ExecPageContainer extends Component { this.props.eventCreationMode ? this.onQuitEventCreationMode() : ''; this.props.eventAutomationMode ? this.onQuitEventAutomationMode() : ''; this.props.eventReplayMode ? this.onQuitEventReplayMode() : ''; + this.props.viewMode ? this.onQuitViewMode() : ''; // Retrieve list of available scenarios this.props.cfgApi.getScenarioList((error, data, response) => { @@ -255,6 +260,11 @@ class ExecPageContainer extends Component { this.props.changeEventCreationMode(false); } + // CLOSE VIEW PANE + onQuitViewMode() { + this.props.changeViewMode(false); + } + // CLOSE EVENT AUTOMATION PANE onQuitEventAutomationMode() { this.props.changeEventAutomationMode(false); @@ -265,6 +275,14 @@ class ExecPageContainer extends Component { this.props.changeEventReplayMode(false); } + // CONFIGURE DASHBOARD + onOpenViewMode() { + this.props.changeViewMode(true); + this.props.changeEventCreationMode(false); + this.props.changeEventAutomationMode(false); + this.props.changeEventReplayMode(false); + } + // CONFIGURE DASHBOARD onOpenDashCfg() { this.props.changeDashCfgMode(true); @@ -275,6 +293,11 @@ class ExecPageContainer extends Component { this.props.changeDashCfgMode(false); } + // STOP CONFIGURE DASHBOARD + onCloseViewMode() { + this.props.changeViewMode(false); + } + // CONFIGURE EVENTS onOpenEventCfg() { this.props.changeEventCfgMode(true); @@ -366,7 +389,7 @@ class ExecPageContainer extends Component { (this.props.scenarioState !== EXEC_STATE_IDLE) ? this.props.execScenarioName : 'None' : this.props.cfgScenarioName; - const eventPaneOpen = this.props.eventCreationMode || this.props.eventAutomationMode || this.props.eventReplayMode; + const eventPaneOpen = this.props.eventCreationMode || this.props.eventAutomationMode || this.props.eventReplayMode || this.props.viewMode; const spanLeft = eventPaneOpen ? 8 : 12; const spanRight = eventPaneOpen ? 4 : 0; return ( @@ -417,6 +440,7 @@ class ExecPageContainer extends Component { onTerminate={this.onTerminateScenario} onOpenDashCfg={this.onOpenDashCfg} onOpenEventCfg={this.onOpenEventCfg} + onOpenViewMode={this.onOpenViewMode} /> @@ -477,6 +501,16 @@ class ExecPageContainer extends Component { onClose={this.onQuitEventAutomationMode} /> + + + )} @@ -513,6 +547,7 @@ const mapStateToProps = state => { scenarioState: state.exec.state.scenario, scenarios: state.exec.apiResults.scenarios, eventCreationMode: state.ui.eventCreationMode, + viewMode: state.ui.viewMode, eventAutomationMode: state.ui.eventAutomationMode, eventReplayMode: state.ui.eventReplayMode, dashCfgMode: state.ui.dashCfgMode, @@ -534,6 +569,7 @@ const mapDispatchToProps = dispatch => { changeEventReplayMode: val => dispatch(uiExecChangeEventReplayMode(val)), // (true or false) changeDashCfgMode: val => dispatch(uiExecChangeDashCfgMode(val)), // (true or false) changeEventCfgMode: val => dispatch(uiExecChangeEventCfgMode(val)), // (true or false) + changeViewMode: val => dispatch(uiExecChangeViewMode(val)), // (true or false) changeCurrentEvent: e => dispatch(uiExecChangeCurrentEvent(e)), execChangeOkToTerminate: ok => dispatch(execChangeOkToTerminate(ok)), changeShowApps: show => dispatch(uiExecChangeShowApps(show)), diff --git a/js-apps/meep-frontend/src/js/containers/exec/exec-page-scenario-buttons.js b/js-apps/meep-frontend/src/js/containers/exec/exec-page-scenario-buttons.js index fd37795d0..03f10e72e 100644 --- a/js-apps/meep-frontend/src/js/containers/exec/exec-page-scenario-buttons.js +++ b/js-apps/meep-frontend/src/js/containers/exec/exec-page-scenario-buttons.js @@ -65,7 +65,7 @@ class ExecPageScenarioButtons extends Component { ); } - canOpenDashCfg() { + canOpenViewMode() { return ( this.props.sandbox && !this.props.podsPending && @@ -125,8 +125,8 @@ class ExecPageScenarioButtons extends Component {