Commit 2862f3f8 authored by wangdong's avatar wangdong

done

parent 7aef45d7
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
"vue-electron": "^1.0.6", "vue-electron": "^1.0.6",
"vue-json-tree-view": "^2.1.6", "vue-json-tree-view": "^2.1.6",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue2-highcharts": "^1.2.5" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"ajv": "^6.5.0", "ajv": "^6.5.0",
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>slice</title> <title>AI-Engine OpenXG® </title>
<% if (htmlWebpackPlugin.options.nodeModules) { %> <% if (htmlWebpackPlugin.options.nodeModules) { %>
<!-- Add `node_modules/` to global paths so `require` works properly in development --> <!-- Add `node_modules/` to global paths so `require` works properly in development -->
<script> <script>
......
...@@ -2,6 +2,7 @@ import { app, BrowserWindow,BrowserView, ipcMain,Menu,shell,screen,ipcRenderer} ...@@ -2,6 +2,7 @@ import { app, BrowserWindow,BrowserView, ipcMain,Menu,shell,screen,ipcRenderer}
import { runInDebugContext } from 'vm' import { runInDebugContext } from 'vm'
const isMac = process.platform === 'darwin' const isMac = process.platform === 'darwin'
let FlexRAN = false let FlexRAN = false
let url = "ustb-oai.com"
const template = [ const template = [
// { role: 'appMenu' } // { role: 'appMenu' }
...(isMac ? [{ ...(isMac ? [{
...@@ -25,15 +26,8 @@ const template = [ ...@@ -25,15 +26,8 @@ const template = [
{ {
label: 'FlexRAN Drone® Mosaic5G ', label: 'FlexRAN Drone® Mosaic5G ',
click() { click() {
//shell.openExternal('http://192.168.1.36');
// if(!FlexRAN){
openFlexran() openFlexran()
// FlexRAN = !FlexRAN
// }
// else{
// closeFlexran()
// FlexRAN = !FlexRAN
// }
}, },
}, },
...@@ -95,7 +89,7 @@ const template = [ ...@@ -95,7 +89,7 @@ const template = [
label: 'Learn More', label: 'Learn More',
click: async () => { click: async () => {
const { shell } = require('electron') const { shell } = require('electron')
await shell.openExternal('https://electronjs.org') await shell.openExternal('http://ustb-oai.com')
} }
} }
] ]
...@@ -142,6 +136,7 @@ function createNewWindow(host,user,pass){ ...@@ -142,6 +136,7 @@ function createNewWindow(host,user,pass){
} }
}) })
win.loadURL(winURL+`/#/ssh/${host}/start_enb/${user==undefined?'root':user}/${pass==undefined?'199710':pass}/`) win.loadURL(winURL+`/#/ssh/${host}/start_enb/${user==undefined?'root':user}/${pass==undefined?'199710':pass}/`)
//win.loadURL(winURL+`/#/prb/`)
newWindows.push(win) newWindows.push(win)
} }
...@@ -171,12 +166,6 @@ Menu.setApplicationMenu( Menu.buildFromTemplate(template)); ...@@ -171,12 +166,6 @@ Menu.setApplicationMenu( Menu.buildFromTemplate(template));
}) })
} }
function openFlexran(){ function openFlexran(){
// view = new BrowserView()
// mainWindow.setBrowserView(view)
// console.log(mainWindow.getContentBounds())
// view.setBounds({ x: 1364, y: 0, width: 556, height: mainWindow.getContentBounds()["height"] })
// view.webContents.loadURL("http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710")
// view.setAutoResize({width:true,height:true, horizontal:true,vertical:true})
child = new BrowserWindow({ child = new BrowserWindow({
minWidth:500, minWidth:500,
minHeight:500, minHeight:500,
...@@ -189,19 +178,11 @@ function openFlexran(){ ...@@ -189,19 +178,11 @@ function openFlexran(){
webSecurity: false webSecurity: false
} }
}) })
// view1 = new BrowserView()
// child.setBrowserView(view1)
// console.log(child.getContentBounds())
// view1.setBounds({ x: 1364, y: 0, width: 556, height: child.getContentBounds()["height"] })
// view1.webContents.loadURL("http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710")
// view1.setAutoResize({width:true,height:true, horizontal:true,vertical:true})
console.log(winURL) console.log(winURL)
child.loadURL('http://ustb-oai.com:2224') child.loadURL(`http://${url}:2224`)
} }
function closeFlexran(){
view.setBounds({ x: 0, y: 0, width: 0, height: 0 })
}
...@@ -228,6 +209,12 @@ app.on('resize', (e, cmd) => { ...@@ -228,6 +209,12 @@ app.on('resize', (e, cmd) => {
console.log("aaa") console.log("aaa")
}) })
ipcMain.on('change-url', function(event, arg) {
console.log(arg); // prints "ping"
url = arg
event.returnValue = 'pong';
});
/** /**
* Auto Updater * Auto Updater
* *
......
<template> <template>
<div id="first"> <div id="first">
<div id="wrapper"> <div id="wrapper">
<main> <main>
<div id="left" class="left-side"> <div id="left" class="left-side">
<img src="~@/assets/ustb-oai.com.png" alt="electron-vue" width="350px" > <img
<slice-information></slice-information> src="~@/assets/ustb-oai.com.png"
</div> alt="electron-vue"
width="350px"
<div class="right-side"> />
<base-station-info></base-station-info> <slice-information></slice-information>
</div> </div>
</main>
<div class="right-side">
<base-station-info></base-station-info>
</div>
</main>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import SystemInformation from './LandingPage/SystemInformation' import SystemInformation from "./LandingPage/SystemInformation";
import SliceInformation from './sliceInfos/SliceInformation' import SliceInformation from "./sliceInfos/SliceInformation";
import BaseStationInfo from './sliceInfos/BaseStationInfo' import BaseStationInfo from "./sliceInfos/BaseStationInfo";
import SshPage from './SshPage/SshPage' import SshPage from "./SshPage/SshPage";
import UeLists from './sliceInfos/UeLists' import UeLists from "./sliceInfos/UeLists";
import * as flexranAPI from "../../utils/flexranAPI" import * as flexranAPI from "../../utils/flexranAPI";
import {ipcRenderer} from 'electron' import { ipcRenderer } from "electron";
export default {
name: "landing-page",
components: {
SystemInformation,
"slice-information": SliceInformation,
"ue-lists": UeLists,
"base-station-info": BaseStationInfo,
"ssh-page": SshPage,
},
async mounted() {
console.log(this.$store);
let res = await flexranAPI.DETECT({});
export default { try {
name: 'landing-page', let returnCitySN = JSON.parse(res.split("= ")[1].split(";")[0]);
components: { SystemInformation ,'slice-information':SliceInformation,"ue-lists":UeLists,"base-station-info":BaseStationInfo,"ssh-page":SshPage}, let local = await flexranAPI.DETECT_LOCAL({}, returnCitySN["cip"]);
mounted(){ if (local.area == "北京科技大学") {
console.log("在校园网内");
ipcRenderer.sendSync("change-url", "10.25.20.227");
flexranAPI.SET_URL({});
} else {
console.log("不在校园网");
}
} catch (error) {
console.log("在校园网内");
ipcRenderer.sendSync("change-url", "10.25.20.227");
flexranAPI.SET_URL({});
}
this.timeInterval1 = setInterval(() => {
flexranAPI.GET_MAC_STATS().then((result) => {
let dataList =
result.eNB_config[0].eNB.cellConfig[0].sliceConfig.dl.slices;
let ue_list = result.mac_stats[0].ue_list
this.$store.commit("updateSlices", {
slice_info: dataList,
});
this.$store.commit("updateUes", {
ue_list: ue_list,
});
dataList.forEach(e => {
e = e.ddqn
});
this.$store.commit("updatePrbs", {
prb_info: dataList,
});
// console.log(dataList)
});
}, 500);
},
methods: {
open(link) {
this.$electron.shell.openExternal(link);
}, },
methods: { openFlexran() {
open (link) { ipcRenderer.send("openFlexran");
this.$electron.shell.openExternal(link)
},
openFlexran () {
ipcRenderer.send('openFlexran')
}, },
closeFlexran () { closeFlexran() {
ipcRenderer.send('closeFlexran') ipcRenderer.send("closeFlexran");
} },
} },
} };
</script> </script>
<style> <style>
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro'); @import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro");
* { * {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
html,body,#app{ html,
height: 100%; body,
#app {
height: 100%;
} }
body { font-family: 'Source Sans Pro', sans-serif; } body {
img { font-family: "Source Sans Pro", sans-serif;
filter:grayscale(70%); }
display: fixed; img {
bottom: 2px; filter: grayscale(70%);
display: fixed;
bottom: 2px;
} }
header { header {
margin-top: 15px; margin-top: 15px;
} }
#wrapper { #wrapper {
background: background: radial-gradient(
radial-gradient( ellipse at top left,
ellipse at top left, rgba(255, 255, 255, 1) 40%,
rgba(255, 255, 255, 1) 40%, rgba(229, 229, 229, 0.9) 100%
rgba(229, 229, 229, .9) 100% );
); height: 100vh;
height: 100vh; padding: 15px 20px;
padding: 15px 20px; width: 100vw;
width: 100vw; }
} #left {
#left { padding-right: 10px;
padding-right:10px ; }
} .right-side {
.right-side{ margin-top: 76.39px;
margin-top: 76.39px; }
} main {
main { display: flex;
display: flex; justify-content: space-between;
justify-content: space-between; margin-right: 56px;
margin-right: 56px; }
}
main > div { flex-basis: 50%; }
.left-side { main > div {
display: flex; flex-basis: 50%;
flex-direction: column; }
}
#first {
height: 100%;
}
.left-side {
display: flex;
flex-direction: column;
}
#first {
height: 100%;
}
.doc button { .doc button {
font-size: .8em; font-size: 0.8em;
cursor: pointer; cursor: pointer;
outline: none; outline: none;
padding: 0.75em 2em; padding: 0.75em 2em;
border-radius: 2em; border-radius: 2em;
display: inline-block; display: inline-block;
color: #fff; color: #fff;
background-color: #4fc08d; background-color: #4fc08d;
transition: all 0.15s ease; transition: all 0.15s ease;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #4fc08d; border: 1px solid #4fc08d;
} }
.doc button.alt { .doc button.alt {
color: #42b983; color: #42b983;
background-color: transparent; background-color: transparent;
} }
</style> </style>
<template>
<div style="height:100%">
<iframe id="show-iframe" style="height:500px;width:100%" frameborder=0 name="showHere" scrolling=auto :src="src"></iframe>
<!-- <img src="~@/assets/ustb-oai.com.png" alt="electron-vue" height="4%" > -->
</div>
</template>
<script>
import Vue from "vue";
import vueJsonTreeView from "vue-json-tree-view";
import * as flexranAPI from "../../../utils/flexranAPI";
Vue.use(vueJsonTreeView);
export default {
data() {
return {
dataList:[],
host:'',
action:'',
src:'http://10.25.20.227:2224'
};
},
async mounted() {
this.host=this.$route.params.host
this.action=this.$route.params.action
this.user=this.$route.params.user
this.pass=this.$route.params.pass
let res = await flexranAPI.DETECT({})
try {
let returnCitySN = JSON.parse(res.split("= ")[1].split(";")[0])
let local = await flexranAPI.DETECT_LOCAL({},returnCitySN['cip'])
if(local.area=="北京科技大学"){
this.src=`http://10.25.20.227:2224`
}
else{
this.src=`http://ustb-oai.com:2224`
}
} catch (error) {
this.src=`http://10.25.20.227:2224`
}
},
methods:{
getJS (){
var child = document.getElementById("show-iframe").contentWindow;
let a= child.document.getElementById("menu");
console.log(a)
}
},
};
</script>
<style>
html,body,#app{
height: 100%;
}
.left{}
</style>
...@@ -19,12 +19,28 @@ export default { ...@@ -19,12 +19,28 @@ export default {
src:'http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710' src:'http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710'
}; };
}, },
mounted() { async mounted() {
this.host=this.$route.params.host this.host=this.$route.params.host
this.action=this.$route.params.action this.action=this.$route.params.action
this.user=this.$route.params.user this.user=this.$route.params.user
this.pass=this.$route.params.pass this.pass=this.$route.params.pass
this.src=`http://10.25.20.227:2222/ssh/host/${this.host}?autologin=1&user=${this.user}&pass=${this.pass}` let res = await flexranAPI.DETECT({})
try {
let returnCitySN = JSON.parse(res.split("= ")[1].split(";")[0])
let local = await flexranAPI.DETECT_LOCAL({},returnCitySN['cip'])
if(local.area=="北京科技大学"){
this.src=`http://10.25.20.227:2222/ssh/host/${this.host}?autologin=1&user=${this.user}&pass=${this.pass}`
}
else{
this.src=`http://ustb-oai.com:2222/ssh/host/${this.host}?autologin=1&user=${this.user}&pass=${this.pass}`
}
} catch (error) {
this.src=`http://10.25.20.227:2222/ssh/host/${this.host}?autologin=1&user=${this.user}&pass=${this.pass}`
}
}, },
methods:{ methods:{
......
...@@ -5,7 +5,24 @@ ...@@ -5,7 +5,24 @@
<el-table-column type="index" label="UE"></el-table-column> <el-table-column type="index" label="UE"></el-table-column>
<el-table-column prop="rnti" label="RNTI" width="100"> <el-table-column prop="rnti" label="RNTI" width="100">
</el-table-column> </el-table-column>
<el-table-column prop="Mbs" label="速度"> </el-table-column> <el-table-column label="速度">
<template slot-scope="scope">
<el-popover
placement="right"
width="400"
trigger="hover"
>
<div v-html="pingInfo"></div>
<div
style="margin: 10px"
@mouseover="hover = scope.row.imsi"
@mouseleave="hover = false"
slot="reference"
>
<el-button >{{ scope.row.Mbs }}</el-button></div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="切片"> <el-table-column label="切片">
<template slot-scope="scope"> <template slot-scope="scope">
<el-dropdown> <el-dropdown>
...@@ -18,7 +35,10 @@ ...@@ -18,7 +35,10 @@
:key="index1" :key="index1"
v-bind="item1" v-bind="item1"
>分配至:切片{{ item1.id }} >分配至:切片{{ item1.id }}
<el-tag effect="dark" @click="changeslice(scope.row.imsi,item1.id)"> <el-tag
effect="dark"
@click="changeslice(scope.row.imsi, item1.id)"
>
{{ item1.label }} {{ item1.label }}
</el-tag></el-dropdown-item </el-tag></el-dropdown-item
> >
...@@ -38,57 +58,86 @@ import * as flexranAPI from "../../../utils/flexranAPI"; ...@@ -38,57 +58,86 @@ import * as flexranAPI from "../../../utils/flexranAPI";
export default { export default {
data() { data() {
return { return {
dataList: [], hover: false,
slices: [], pingInfo:
"PING 172.16.0.x (172.16.0.x) 56(84) bytes of data.<br/>64 bytes from 172.16.0.6: icmp_seq=1 ttl=64 time=39.5 ms<br/>64 bytes from 172.16.0.6: icmp_seq=2 ttl=64 time=39.1 ms<br/>64 bytes from 172.16.0.6: icmp_seq=3 ttl=64 time=28.7 ms<br/>64 bytes from 172.16.0.6: icmp_seq=4 ttl=64 time=45.6 ms<br/><br/>--- 172.16.0.6 ping statistics ---<br/>4 packets transmitted, 4 received, 0% packet loss, time 242ms<br/>rtt min/avg/max/mdev = 28.799/38.307/45.687/6.068 ms<br/>",
}; };
}, },
created() { created() {
this.getDataList(); this.getDataList();
}, },
computed: {
slices() {
return this.$store.state.slice_info;
},
dataList() {
return this.$store.state.ue_list;
},
},
watch: {
hover: {
handler(newValue, oldValue) {
console.log(this.hover);
if (this.hover !== false) {
this.getping(this.hover);
}
if (this.hover == false) {
clearInterval(this.timer);
}
},
deep: true,
},
},
methods: { methods: {
getDataList() { async getping(imsi) {
this.timeInterval = setInterval(async () => { this.timer = setInterval(() => {
let res = await flexranAPI.GET_MAC_STATS({}); flexranAPI.SEND_PING({ imsi: imsi }).then((result) => {
this.dataList = res.mac_stats[0].ue_list; this.pingInfo = result.output.split("\n").join("<br/>");
this.slices = res.eNB_config[0].eNB.cellConfig[0].sliceConfig.dl.slices; });
}, 1000); }, 1000);
}, },
changeslice(imsi,to) { getDataList() {},
this.$confirm(`是否将${imsi}切换到切片${to}`, '提示', { changeslice(imsi, to) {
confirmButtonText: '确定', this.$confirm(`是否将${imsi}切换到切片${to}`, "提示", {
cancelButtonText: '取消', confirmButtonText: "确定",
type: 'info' cancelButtonText: "取消",
}).then(() => { type: "info",
flexranAPI.CHANGE_SLICE_ASSOC({ })
"ueConfig": [ .then(() => {
{ flexranAPI
"imsi": imsi, .CHANGE_SLICE_ASSOC(
"dlSliceId": to, {
} ueConfig: [
] {
},-1).then((res)=>{ imsi: imsi,
console.log(res) dlSliceId: to,
if(res.status=='Ok'){ },
this.$message({ ],
type: 'success', },
message: '切换成功!' -1
}); )
} .then((res) => {
else{ console.log(res);
this.$message({ if (res.status == "Ok") {
type: 'error', this.$message({
message: res.status type: "success",
}); message: "切换成功!",
} });
}) } else {
this.$message({
}).catch(() => { type: "error",
message: res.status,
});
}
});
})
.catch(() => {
this.$message({ this.$message({
type: 'info', type: "info",
message: '已取消切换' message: "已取消切换",
}); });
}); });
} },
}, },
}; };
</script> </script>
......
<template>
<div>
<canvas
id="mycanvas"
width="1000"
height="1000"
style="text-align: center"
></canvas>
</div>
</template>
<script>
import Vue from "vue";
import vueJsonTreeView from "vue-json-tree-view";
import * as flexranAPI from "../../../utils/flexranAPI";
import Tooltip from "element-ui";
Vue.use(vueJsonTreeView);
Vue.use(Tooltip);
export default {
data() {
return {
hover: false,
ue_list: [],
slice_conf: [],
color_arrs:["#909399","#F56C6C","#E6A23C","#67C23A"],
pingInfo:
"PING 172.16.0.x (172.16.0.x) 56(84) bytes of data.<br/>64 bytes from 172.16.0.6: icmp_seq=1 ttl=64 time=39.5 ms<br/>64 bytes from 172.16.0.6: icmp_seq=2 ttl=64 time=39.1 ms<br/>64 bytes from 172.16.0.6: icmp_seq=3 ttl=64 time=28.7 ms<br/>64 bytes from 172.16.0.6: icmp_seq=4 ttl=64 time=45.6 ms<br/><br/>--- 172.16.0.6 ping statistics ---<br/>4 packets transmitted, 4 received, 0% packet loss, time 242ms<br/>rtt min/avg/max/mdev = 28.799/38.307/45.687/6.068 ms<br/>",
visible: false,
};
},
computed: {
slices(){
return this.$store.state.slice_info
},
dataList(){
return this.$store.state.ue_list
},
prb_info(){
return this.$store.state.prb_info
}
},
mounted() {
console.log(this.$store.state.prb_info)
let canvas = document.getElementById("mycanvas");
let ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 500;
let width = 600;
let height = 500;
let rectH = 20;
let rectW = 20;
ctx.lineWidth = 0.5;
  ctx.font="25px 宋体";
//绘制表格
// 第一步: 绘制横线
for(let i=0;i<=width/20;i++){
ctx.moveTo(rectW*i,0);
//如果不设置moveTo,当前画笔没有位置
ctx.lineTo(rectW*i,height);
if(i==0){
ctx.lineTo((rectW+1)*i,height);
}
}
//第二步:绘制竖线:如果绘制的格子的宽高相等,可以将for循环放到一个里面;
for(let i=0;i<=height/20;i++){
ctx.moveTo(0,rectH*i);
ctx.lineTo(width,rectH*i);
}
  //strokeText(text: String, x: Number, y: Number, maxWidth: Number): none
ctx.stroke();
},
methods: {
async getping(imsi) {
this.timer = setInterval(() => {
flexranAPI.SEND_PING({ imsi: imsi }).then((result) => {
this.pingInfo = result.output.split("\n").join("<br/>");
});
}, 1000);
},
drawCell(x,y){
let canvas=document.getElementById("mycanvas");
let ctx=canvas.getContext('2d');
ctx.fillStyle="#aaa"
ctx.fillRect(x,y,19,19);
ctx.font="700";
ctx.stroke();
return ctx
},
clearClomnCell(x){
for(let i=0;i<25;i++){
let canvas=document.getElementById("mycanvas");
let ctx=canvas.getContext('2d');
ctx.clearRect(x,i*20,19,19);
ctx.stroke();
}
},
drawClomnCell(x,data){
let count=0
this.clearClomnCell(x)
for(let i =0;i<data.length;i++){
let prb
if(data[i].id!="0"){
if(count<24 && data[i].ddqn.mrb>0){
prb = (data[i].ddqn.mrb+1)*2>25?25:(data[i].ddqn.mrb)*2
}
else{
prb = (data[i].ddqn.mrb+1)*2>25?25:((data[i].ddqn.mrb)*2)
}
}
else{
prb = (data[i].ddqn.mrb)*2>25?25:data[i].ddqn.mrb*2
}
for(let j=count;j<prb+count;j++){
let canvas=document.getElementById("mycanvas");
let ctx=canvas.getContext('2d');
ctx.fillStyle=this.color_arrs[data[i].id]
ctx.fillRect(x,j*20,19,19);
ctx.stroke();
}
count+=prb
}
}
},
watch: {
prb_info: {
handler(newValue, oldValue) {
newValue.forEach((v,i)=>{
this.drawClomnCell(i*20,v)
})
},
deep: true,
},
hover: {
handler(newValue, oldValue) {
console.log(this.hover);
if (this.hover !== false) {
this.getping(this.hover);
}
if (this.hover == false) {
clearInterval(this.timer);
}
},
deep: true,
},
},
};
</script>
<style scoped>
.title {
color: #888;
font-size: 18px;
font-weight: initial;
letter-spacing: 0.25px;
margin-top: 10px;
}
.items {
margin-top: 8px;
}
.item {
display: flex;
margin-bottom: 6px;
}
.item .name {
color: #6a6a6a;
margin-right: 6px;
}
.item .value {
color: #35495e;
font-weight: bold;
}
</style>
<template> <template>
<div> <div>
<el-card> <el-card>
<el-table :data="dataList" border stripe> <el-popover
<el-table-column prop="id" label="网络切片ID"></el-table-column> placement="right"
width="620"
trigger="hover">
<prb-info></prb-info>
<el-button slot="reference">时频图</el-button>
</el-popover>
<el-table :data="slice_info" border stripe>
<el-table-column label="网络切片ID">
<template slot-scope="scope">
<el-button :type="color_arrs[scope.row.id]" circle> {{ scope.row.id }}</el-button>
</template>
</el-table-column>
<el-table-column prop="label" label="切片类型" width="100"> <el-table-column prop="label" label="切片类型" width="100">
</el-table-column> </el-table-column>
<el-table-column label="吞吐量(Mps)"> <el-table-column label="吞吐量(Mps)">
...@@ -27,6 +40,10 @@ ...@@ -27,6 +40,10 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card> </el-card>
<flex-ran></flex-ran>
<!-- <iframe id="show-iframe" style="height:500px;width:100%" frameborder=0 name="showHere" scrolling=auto :src="src"></iframe> --> <!-- <iframe id="show-iframe" style="height:500px;width:100%" frameborder=0 name="showHere" scrolling=auto :src="src"></iframe> -->
</div> </div>
</template> </template>
...@@ -34,7 +51,9 @@ ...@@ -34,7 +51,9 @@
<script> <script>
import Vue from "vue"; import Vue from "vue";
import vueJsonTreeView from "vue-json-tree-view"; import vueJsonTreeView from "vue-json-tree-view";
import PRBInfo from "./PRBInfo";
import * as flexranAPI from "../../../utils/flexranAPI"; import * as flexranAPI from "../../../utils/flexranAPI";
import FlexRan from '../SshPage/FlexRan.vue';
// 渲染进程接收主进程的传参 // 渲染进程接收主进程的传参
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
...@@ -43,69 +62,81 @@ export default { ...@@ -43,69 +62,81 @@ export default {
data() { data() {
return { return {
dataList: [], dataList: [],
src: "http://ustb-oai.com:2224", color_arrs:["info","danger","warning","success"],
slices_getter: "a",
}; };
}, },
mounted() { components: { "prb-info": PRBInfo,"flex-ran":FlexRan },
let a = { computed: {
"dl": { slice_info(){
"algorithm": "DDQN", return this.$store.state.slice_info
"slices": [ },
{ getterSlice(){
"id": 0, return this.$store.getters.getterSlice
"label":"Besteffort",
"ddqn": {
"typeid": 0,
"arb": 0,
"mrb": 0,
}
}
]
}
} }
},
watch:{
// slice_info:{
// function(val, oldVal) {console.log(val,oldVal)},
// deep: true
// }
}
,
mounted() {
let a = {
dl: {
algorithm: "DDQN",
slices: [
{
id: 0,
label: "Besteffort",
ddqn: {
typeid: 0,
arb: 0,
mrb: 0,
},
},
],
},
};
ipcRenderer.on("eNB", (event, arg) => { ipcRenderer.on("eNB", (event, arg) => {
if (arg) { if (arg) {
flexranAPI.START_ENB({}) flexranAPI.START_ENB({});
const loading = this.$loading({ const loading = this.$loading({
lock: true, lock: true,
text: 'Loading', text: "Loading",
spinner: 'el-icon-loading', spinner: "el-icon-loading",
background: 'rgba(0, 0, 0, 0.7)' background: "rgba(0, 0, 0, 0.7)",
}); });
setTimeout(() => { setTimeout(() => {
flexranAPI.ADD_SLICE(a,-1) flexranAPI.ADD_SLICE(a, -1);
loading.close(); loading.close();
this.$message({ this.$message({
message: '成功启动OAI基站', message: "成功启动OAI基站",
type: 'success' type: "success",
}); });
}, 4000); }, 4000);
} }
}); });
ipcRenderer.on("eNBl2", (event, arg) => { ipcRenderer.on("eNBl2", (event, arg) => {
if (arg) { if (arg) {
flexranAPI.START_ENB_L2({}) flexranAPI.START_ENB_L2({});
const loading = this.$loading({ const loading = this.$loading({
lock: true, lock: true,
text: 'Loading', text: "Loading",
spinner: 'el-icon-loading', spinner: "el-icon-loading",
background: 'rgba(0, 0, 0, 0.7)' background: "rgba(0, 0, 0, 0.7)",
}); });
setTimeout(() => { setTimeout(() => {
loading.close(); loading.close();
this.$message({ this.$message({
message: '成功启动OAI基站', message: "成功启动OAI基站",
type: 'success' type: "success",
}); });
}, 2000); }, 2000);
} }
}); });
this.timeInterval = setInterval(() => {
flexranAPI.GET_MAC_STATS().then((result) => {
this.dataList =
result.eNB_config[0].eNB.cellConfig[0].sliceConfig.dl.slices;
});
}, 1000);
}, },
}; };
</script> </script>
......
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios' import axios from 'axios'
import ElementUI from 'element-ui'; import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; import 'element-ui/lib/theme-chalk/index.css';
import App from './App' import App from './App'
import router from './router' import router from './router'
import {Table} from 'element-ui' import {Table} from 'element-ui'
import store from './store/index';
if (!process.env.IS_WEB) Vue.use(require('vue-electron')) if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
Vue.http = Vue.prototype.$http = axios Vue.http = Vue.prototype.$http = axios
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.use(Table); Vue.use(Table);
Vue.use(ElementUI); Vue.use(ElementUI);
Vue.use(Vuex);
/* eslint-disable no-new */ /* eslint-disable no-new */
new Vue({ new Vue({
components: { App }, components: { App },
router, router,
store,
template: '<App/>' template: '<App/>'
}).$mount('#app') }).$mount('#app')
import Vue from 'vue' import Vue from 'vue'
import Router from 'vue-router' import Router from 'vue-router'
import BaseStationInfo from '../components/sliceInfos/BaseStationInfo' import BaseStationInfo from '../components/sliceInfos/BaseStationInfo'
import PRBInfo from '../components/sliceInfos/PRBInfo'
import SshPage from '../components/SshPage/SshPage' import SshPage from '../components/SshPage/SshPage'
import FlexRan from '../components/SshPage/FlexRan'
Vue.use(Router) Vue.use(Router)
let router =[ let router =[
...@@ -14,6 +16,11 @@ let router =[ ...@@ -14,6 +16,11 @@ let router =[
path: '/ssh/:host/:action/:user/:pass', path: '/ssh/:host/:action/:user/:pass',
name: 'ssh-page', name: 'ssh-page',
component: SshPage component: SshPage
},
{
path: '/flexran',
name: 'flex-ran',
component: FlexRan
} }
] ]
......
const actions = {
updateSlcie(context) {
context.commit('updateSlices', {
num: 2
})
}
}
export default actions;
\ No newline at end of file
const getters = {
getterSlice(state) {
console.log(state);
return state.slice_info;
}
}
export default getters;
\ No newline at end of file
import Vue from 'vue';
import Vuex from 'vuex';
import state from './rootState.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
Vue.use(Vuex);
const store = new Vuex.Store({
state,
getters,
actions,
mutations
});
export default store;
const mutations = {
updateSlices(state, obj) {
return state.slice_info = obj.slice_info;
},
updateUes(state, obj) {
return state.ue_list = obj.ue_list;
} ,
updatePrbs(state, obj) {
if(state.prb_info.length==30){
state.prb_info.shift();
}
return state.prb_info.push(obj.prb_info);
}
}
export default mutations;
\ No newline at end of file
const state = {
slice_info:[],
ue_list:[],
prb_info:[]
}
export default state;
\ No newline at end of file
import { service, request } from './network_services' import { service, request } from './network_services'
let url = `ustb-oai.com`
export function SET_URL (data = {}) {
// 接口请求
url="10.25.20.227"
}
export function GET_URL (data = {}) {
// 接口请求
return url
}
/** /**
* @description 获取MAC_Stats * @description 获取MAC_Stats
...@@ -7,8 +17,8 @@ import { service, request } from './network_services' ...@@ -7,8 +17,8 @@ import { service, request } from './network_services'
export function GET_MAC_STATS (data = {}) { export function GET_MAC_STATS (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://192.168.1.12:8110/api/stats', url: `http://${url}:8110/api/stats`,
method: 'get', method: `get`,
data data
}) })
} }
...@@ -19,8 +29,8 @@ import { service, request } from './network_services' ...@@ -19,8 +29,8 @@ import { service, request } from './network_services'
export function START_ENB (data = {}) { export function START_ENB (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://192.168.1.12:8110/api/startenb', url: `http://${url}:8110/api/startenb`,
method: 'get', method: `get`,
data data
}) })
} }
...@@ -31,8 +41,8 @@ import { service, request } from './network_services' ...@@ -31,8 +41,8 @@ import { service, request } from './network_services'
export function START_ENB_L2 (data = {}) { export function START_ENB_L2 (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://192.168.1.12:8110/api/startenbl2', url: `http://${url}:8110/api/startenbl2`,
method: 'get', method: `get`,
data data
}) })
} }
...@@ -43,8 +53,8 @@ import { service, request } from './network_services' ...@@ -43,8 +53,8 @@ import { service, request } from './network_services'
export function GET_IPV4_IMSI (data = {}) { export function GET_IPV4_IMSI (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://192.168.1.12:8110/api/getip', url: `http://${url}:8110/api/getip`,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -55,8 +65,8 @@ import { service, request } from './network_services' ...@@ -55,8 +65,8 @@ import { service, request } from './network_services'
export function SEND_PING (data = {}) { export function SEND_PING (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://192.168.1.12:8110/api/pingapp', url: `http://${url}:8110/api/pingapp`,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -67,8 +77,8 @@ import { service, request } from './network_services' ...@@ -67,8 +77,8 @@ import { service, request } from './network_services'
export function ENABLE_ELASTIC (data = {}) { export function ENABLE_ELASTIC (data = {}) {
// 接口请求 // 接口请求
return request({ return request({
url: '/elasticmon/enable', url: `/elasticmon/enable`,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -81,8 +91,8 @@ import { service, request } from './network_services' ...@@ -81,8 +91,8 @@ import { service, request } from './network_services'
export function CHANGE_CELL_CONF (data = {}, ENB_ID) { export function CHANGE_CELL_CONF (data = {}, ENB_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: '/conf/enb/' + ENB_ID, url: `/conf/enb/` + ENB_ID,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -101,8 +111,8 @@ import { service, request } from './network_services' ...@@ -101,8 +111,8 @@ import { service, request } from './network_services'
export function ADD_NEW_MME (data = {}, ENB_ID) { export function ADD_NEW_MME (data = {}, ENB_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: '/mme/enb/' + ENB_ID, url: `/mme/enb/` + ENB_ID,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -117,8 +127,8 @@ import { service, request } from './network_services' ...@@ -117,8 +127,8 @@ import { service, request } from './network_services'
export function AUTO_SLICE_ASSOC (data = {}, ENB_ID, SLICE_ID) { export function AUTO_SLICE_ASSOC (data = {}, ENB_ID, SLICE_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: '/auto_ue_slice_assoc/enb/' + ENB_ID + ' /slice/' + SLICE_ID + '/dl', url: `/auto_ue_slice_assoc/enb/` + ENB_ID + ` /slice/` + SLICE_ID + `/dl`,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -139,8 +149,8 @@ import { service, request } from './network_services' ...@@ -139,8 +149,8 @@ import { service, request } from './network_services'
export function CHANGE_SLICE_ASSOC (data = {}, ENB_ID) { export function CHANGE_SLICE_ASSOC (data = {}, ENB_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://ustb-oai.com:9999/ue_slice_assoc/enb/' + ENB_ID, url: `http://${url}:9999/ue_slice_assoc/enb/` + ENB_ID,
method: 'post', method: `post`,
data data
}) })
} }
...@@ -161,14 +171,14 @@ import { service, request } from './network_services' ...@@ -161,14 +171,14 @@ import { service, request } from './network_services'
export function DELETE_SLICE (data = {}, ENB_ID) { export function DELETE_SLICE (data = {}, ENB_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: '/slice/enb/' + ENB_ID, url: `/slice/enb/` + ENB_ID,
method: 'delete', method: `delete`,
data data
}) })
} }
/** /**
* @description This API endpoint posts a new slice configuration to an underlying agent, specified as a JSON file with the format of the sliceConfig as contained in the cellConfig of an agent configuration (for a description of the parameters, see below), or the scheduler to use if no slicing algorithm is chosen (None). It can be used to create arbitrary slices with an arbitrary ID or to change slices by specifying an ID for an existing slice. In the request, a slice ID must be present, as well as the slice parameters. The label is optional, and if no scheduler is given, the scheduler that was active when enabling slicing will be used. The stats call should always be used after triggering this endpoint and sufficient time to verify the actions have been taken. Note that the scheduler (within dl/ul) and the slices parameters are mutually exclusive, since the first only applies for no slicing algorithm (None), whereas the latter only applies if a slicing algorithm has been chosen.This API call has changed as of July 2020. For a description of how the old parameters can be reproduced in the new call, see Deprecated Slice ConfigurationRemarks on the Static slicing algorithm: this algorithm does not provide any sharing. Note that posLow/posHigh are in terms of resource block groups (RBG) in DL and resource blocks (RB) in UL. Furthermore, it is not checked that the channel bandwidth can actually accommodate this slice (posLow=100 and posHigh=110 are a valid entry, but they will never work, since LTE has a maximum bandwidth of 100RBs). Please refer to the stats call to check the amount of resource blocks as well as the resource block group size which will tell the applicable RB/RBG settings. Please also note that OAI reserves the first and last 1, 2, or 3 RBs (for bandwidths 25, 50, or 100RBs, respectively) for PUCCH, meaning that these first/last RBs should be spared out/they won't be given to the slice. Also, the minimum RB size in UL is 3! * @description This API endpoint posts a new slice configuration to an underlying agent, specified as a JSON file with the format of the sliceConfig as contained in the cellConfig of an agent configuration (for a description of the parameters, see below), or the scheduler to use if no slicing algorithm is chosen (None). It can be used to create arbitrary slices with an arbitrary ID or to change slices by specifying an ID for an existing slice. In the request, a slice ID must be present, as well as the slice parameters. The label is optional, and if no scheduler is given, the scheduler that was active when enabling slicing will be used. The stats call should always be used after triggering this endpoint and sufficient time to verify the actions have been taken. Note that the scheduler (within dl/ul) and the slices parameters are mutually exclusive, since the first only applies for no slicing algorithm (None), whereas the latter only applies if a slicing algorithm has been chosen.This API call has changed as of July 2020. For a description of how the old parameters can be reproduced in the new call, see Deprecated Slice ConfigurationRemarks on the Static slicing algorithm: this algorithm does not provide any sharing. Note that posLow/posHigh are in terms of resource block groups (RBG) in DL and resource blocks (RB) in UL. Furthermore, it is not checked that the channel bandwidth can actually accommodate this slice (posLow=100 and posHigh=110 are a valid entry, but they will never work, since LTE has a maximum bandwidth of 100RBs). Please refer to the stats call to check the amount of resource blocks as well as the resource block group size which will tell the applicable RB/RBG settings. Please also note that OAI reserves the first and last 1, 2, or 3 RBs (for bandwidths 25, 50, or 100RBs, respectively) for PUCCH, meaning that these first/last RBs should be spared out/they won`t be given to the slice. Also, the minimum RB size in UL is 3!
* @param {Object} data {"dl":{"algorithm":"SCN19","slices":[ * @param {Object} data {"dl":{"algorithm":"SCN19","slices":[
{"id":0,"scn19":{"typeid":1,"type":"static","posLow":0,"posHigh":8}}, {"id":0,"scn19":{"typeid":1,"type":"static","posLow":0,"posHigh":8}},
{"id":2,"scn19":{"typeid":2,"type":"dynamic","kpsRequired":100,"kpsReference":1200}}, {"id":2,"scn19":{"typeid":2,"type":"dynamic","kpsRequired":100,"kpsReference":1200}},
...@@ -179,8 +189,32 @@ import { service, request } from './network_services' ...@@ -179,8 +189,32 @@ import { service, request } from './network_services'
export function ADD_SLICE (data = {}, ENB_ID) { export function ADD_SLICE (data = {}, ENB_ID) {
// 接口请求 // 接口请求
return request({ return request({
url: 'http://ustb-oai.com:9999/slice/enb/' + ENB_ID, url: `http://${url}:9999/slice/enb/` + ENB_ID,
method: 'post', method: `post`,
data data
}) })
} }
\ No newline at end of file
/**
* @description 探测网络环境
*/
export function DETECT (data = {}) {
// 接口请求
return request({
url: `http://pv.sohu.com/cityjson?ie=utf-8`,
method: `get`,
data
})
}
/**
* @description 获取归属地
*/
export function DETECT_LOCAL (data = {},ip) {
// 接口请求
return request({
url: `https://www.svlik.com/t/ipapi/ip.php?ip=${ip}&type=0`,
method: `get`,
data
})
}
\ No newline at end of file
<template>
<remote-js :src="src"></remote-js>
</template>
<script>
export default {
name: 'OuterIp',
data() {
return {
src: ''
}
},
components: {
'remote-js': {
render(createElement) {
return createElement('script', {
attrs: { type: 'text/javascript', src: this.src || 'http://pv.sohu.com/cityjson?ie=utf-8' }
})
},
props: {
src: { type: String, required: true }
}
}
}
}
</script>
\ No newline at end of file
...@@ -8449,6 +8449,11 @@ vue@^2.5.16: ...@@ -8449,6 +8449,11 @@ vue@^2.5.16:
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123" resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg== integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==
vuex@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71"
integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==
watchpack-chokidar2@^2.0.1: watchpack-chokidar2@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment