Basic stats working
This commit is contained in:
parent
2f6ee379c5
commit
b45b05f033
|
@ -46,7 +46,7 @@ cron.schedule('0 */2 * * * *', () => {
|
||||||
updateAccessPoints().catch(console.log)
|
updateAccessPoints().catch(console.log)
|
||||||
})
|
})
|
||||||
|
|
||||||
cron.schedule('0 */5 * * * *', () => {
|
cron.schedule('0 */1 * * * *', () => {
|
||||||
generateStatsForAllAccessPoints()
|
generateStatsForAllAccessPoints()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ export async function getOnlineWifiDevices() {
|
||||||
apName: client.AP,
|
apName: client.AP,
|
||||||
status: client.ST == 'Online' ? 'ONLINE' : 'OFFLINE',
|
status: client.ST == 'Online' ? 'ONLINE' : 'OFFLINE',
|
||||||
controller: 'Cisco',
|
controller: 'Cisco',
|
||||||
signalStrength: client.SS,
|
signalStrength: client.SS || null,
|
||||||
frequency: client.FB,
|
frequency: client.FB,
|
||||||
protocol: client.PT,
|
protocol: client.PT,
|
||||||
speed: client.SD,
|
speed: client.SD,
|
||||||
|
|
|
@ -191,7 +191,7 @@ export async function getOnlineWifiDevices() {
|
||||||
apName: accessPoints[0].find(ap => ap.mac === client.ap_mac).name,
|
apName: accessPoints[0].find(ap => ap.mac === client.ap_mac).name,
|
||||||
status: 'ONLINE',
|
status: 'ONLINE',
|
||||||
controller: 'UniFi',
|
controller: 'UniFi',
|
||||||
signalStrength: client.signal,
|
signalStrength: client.signal || null,
|
||||||
frequency: null,
|
frequency: null,
|
||||||
protocol: null,
|
protocol: null,
|
||||||
speed: Math.floor(client.tx_rate / 1000),
|
speed: Math.floor(client.tx_rate / 1000),
|
||||||
|
|
|
@ -42,7 +42,9 @@ async function generateStatsForAccessPoint(mac) {
|
||||||
timestamp: timestamp.toISOString(),
|
timestamp: timestamp.toISOString(),
|
||||||
clients: dbStats._count._all,
|
clients: dbStats._count._all,
|
||||||
|
|
||||||
avgSignalStrength: Math.floor(dbStats._avg.signalStrength, 0),
|
avgSignalStrength: dbStats.clients
|
||||||
|
? Math.floor(dbStats._avg.signalStrength, 0)
|
||||||
|
: null,
|
||||||
minSignalStrength: dbStats._min.signalStrength,
|
minSignalStrength: dbStats._min.signalStrength,
|
||||||
maxSignalStrength: dbStats._max.signalStrength,
|
maxSignalStrength: dbStats._max.signalStrength,
|
||||||
|
|
||||||
|
|
|
@ -20,15 +20,21 @@ export const AccessPoint = {
|
||||||
|
|
||||||
usage: (parent, data, context, info) => parent.usage.toString(),
|
usage: (parent, data, context, info) => parent.usage.toString(),
|
||||||
|
|
||||||
stats: async (parent, { take, dateIn, dateOut }, context, info) =>
|
stats: async (parent, { take, dateIn, dateOut }, context, info) => {
|
||||||
prisma.wifiStats.findMany({
|
const stats = await prisma.wifiStats.findMany({
|
||||||
where: {
|
where: {
|
||||||
accessPoint: {
|
accessPoint: {
|
||||||
id: parent.id
|
id: parent.id,
|
||||||
|
timestamp_gte: dateIn,
|
||||||
|
timestamp_lte: dateOut
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
orderBy: { timestamp: 'desc' },
|
||||||
take
|
take
|
||||||
}),
|
})
|
||||||
|
|
||||||
|
return stats.reverse()
|
||||||
|
},
|
||||||
|
|
||||||
latestStats: async (parent, data, context, info) =>
|
latestStats: async (parent, data, context, info) =>
|
||||||
prisma.wifiStats.findFirst({
|
prisma.wifiStats.findFirst({
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const WifiStats = {
|
const WifiStats = {
|
||||||
|
timestamp: parent => parent.timestamp.toString(),
|
||||||
avgUsage: parent => parent.avgUsage.toString(),
|
avgUsage: parent => parent.avgUsage.toString(),
|
||||||
sumUsage: parent => parent.sumUsage.toString()
|
sumUsage: parent => parent.sumUsage.toString()
|
||||||
}
|
}
|
||||||
|
|
27
web/package-lock.json
generated
27
web/package-lock.json
generated
|
@ -11,6 +11,7 @@
|
||||||
"@mdi/font": "^6.6.96",
|
"@mdi/font": "^6.6.96",
|
||||||
"apollo-link-ws": "^1.0.20",
|
"apollo-link-ws": "^1.0.20",
|
||||||
"apollo-utilities": "^1.3.4",
|
"apollo-utilities": "^1.3.4",
|
||||||
|
"chart.js": "^3.8.0",
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"qrcode.vue": "^1.7.0",
|
"qrcode.vue": "^1.7.0",
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
"validator": "^13.7.0",
|
"validator": "^13.7.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-apollo": "^3.1.0",
|
"vue-apollo": "^3.1.0",
|
||||||
|
"vue-chartjs": "^4.1.1",
|
||||||
"vue-json-pretty": "^1.8.2",
|
"vue-json-pretty": "^1.8.2",
|
||||||
"vue-router": "^3.5.3",
|
"vue-router": "^3.5.3",
|
||||||
"vue-the-mask": "^0.11.1",
|
"vue-the-mask": "^0.11.1",
|
||||||
|
@ -8789,6 +8791,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "3.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.0.tgz",
|
||||||
|
"integrity": "sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg=="
|
||||||
|
},
|
||||||
"node_modules/check-types": {
|
"node_modules/check-types": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
||||||
|
@ -22410,6 +22417,15 @@
|
||||||
"graphql-tag": "^2"
|
"graphql-tag": "^2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-chartjs": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rKIQ3jPrjhwxjKdNJppnYxRuBSrx4QeM3nNHsfIxEqjX6QS4Jq6e6vnZBxh2MDpURDC2uvuI2N0eIt1cWXbBVA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": "^3.7.0",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-cli-plugin-apollo": {
|
"node_modules/vue-cli-plugin-apollo": {
|
||||||
"version": "0.22.2",
|
"version": "0.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.22.2.tgz",
|
||||||
|
@ -31273,6 +31289,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "3.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.0.tgz",
|
||||||
|
"integrity": "sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg=="
|
||||||
|
},
|
||||||
"check-types": {
|
"check-types": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
||||||
|
@ -42126,6 +42147,12 @@
|
||||||
"throttle-debounce": "^2.1.0"
|
"throttle-debounce": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-chartjs": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rKIQ3jPrjhwxjKdNJppnYxRuBSrx4QeM3nNHsfIxEqjX6QS4Jq6e6vnZBxh2MDpURDC2uvuI2N0eIt1cWXbBVA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"vue-cli-plugin-apollo": {
|
"vue-cli-plugin-apollo": {
|
||||||
"version": "0.22.2",
|
"version": "0.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.22.2.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"@mdi/font": "^6.6.96",
|
"@mdi/font": "^6.6.96",
|
||||||
"apollo-link-ws": "^1.0.20",
|
"apollo-link-ws": "^1.0.20",
|
||||||
"apollo-utilities": "^1.3.4",
|
"apollo-utilities": "^1.3.4",
|
||||||
|
"chart.js": "^3.8.0",
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"qrcode.vue": "^1.7.0",
|
"qrcode.vue": "^1.7.0",
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
"validator": "^13.7.0",
|
"validator": "^13.7.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-apollo": "^3.1.0",
|
"vue-apollo": "^3.1.0",
|
||||||
|
"vue-chartjs": "^4.1.1",
|
||||||
"vue-json-pretty": "^1.8.2",
|
"vue-json-pretty": "^1.8.2",
|
||||||
"vue-router": "^3.5.3",
|
"vue-router": "^3.5.3",
|
||||||
"vue-the-mask": "^0.11.1",
|
"vue-the-mask": "^0.11.1",
|
||||||
|
|
108
web/src/components/Charts/AccessPointClientsChart.vue
Normal file
108
web/src/components/Charts/AccessPointClientsChart.vue
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<LineChart
|
||||||
|
:chart-options="chartOptions"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:chart-id="chartId"
|
||||||
|
:dataset-id-key="datasetIdKey"
|
||||||
|
:plugins="plugins"
|
||||||
|
:css-classes="cssClasses"
|
||||||
|
:styles="styles"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Line as LineChart } from 'vue-chartjs/legacy'
|
||||||
|
import { time } from '../../plugins/date'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
LineElement,
|
||||||
|
LinearScale,
|
||||||
|
CategoryScale,
|
||||||
|
PointElement
|
||||||
|
} from 'chart.js'
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
LineElement,
|
||||||
|
LinearScale,
|
||||||
|
CategoryScale,
|
||||||
|
PointElement
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { LineChart },
|
||||||
|
|
||||||
|
props: {
|
||||||
|
stats: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chartId: {
|
||||||
|
type: String,
|
||||||
|
default: 'line-chart'
|
||||||
|
},
|
||||||
|
datasetIdKey: {
|
||||||
|
type: String,
|
||||||
|
default: 'label'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: 400
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 250
|
||||||
|
},
|
||||||
|
cssClasses: {
|
||||||
|
default: '',
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
chartOptions: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
chartData() {
|
||||||
|
return {
|
||||||
|
labels: this.stats.map(stat => time(stat.timestamp)),
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Clientes conectados',
|
||||||
|
backgroundColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.primary
|
||||||
|
: this.$vuetify.theme.themes.dark.primary,
|
||||||
|
borderColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.primary
|
||||||
|
: this.$vuetify.theme.themes.dark.primary,
|
||||||
|
borderWidth: 1,
|
||||||
|
data: this.stats.map(stat => stat.clients)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
130
web/src/components/Charts/AccessPointSignalStrengthChart.vue
Normal file
130
web/src/components/Charts/AccessPointSignalStrengthChart.vue
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<LineChart
|
||||||
|
:chart-options="chartOptions"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:chart-id="chartId"
|
||||||
|
:dataset-id-key="datasetIdKey"
|
||||||
|
:plugins="plugins"
|
||||||
|
:css-classes="cssClasses"
|
||||||
|
:styles="styles"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Line as LineChart } from 'vue-chartjs/legacy'
|
||||||
|
import { time } from '../../plugins/date'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
LineElement,
|
||||||
|
LinearScale,
|
||||||
|
CategoryScale,
|
||||||
|
PointElement
|
||||||
|
} from 'chart.js'
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
LineElement,
|
||||||
|
LinearScale,
|
||||||
|
CategoryScale,
|
||||||
|
PointElement
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { LineChart },
|
||||||
|
|
||||||
|
props: {
|
||||||
|
stats: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chartId: {
|
||||||
|
type: String,
|
||||||
|
default: 'line-chart'
|
||||||
|
},
|
||||||
|
datasetIdKey: {
|
||||||
|
type: String,
|
||||||
|
default: 'label'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: 400
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 250
|
||||||
|
},
|
||||||
|
cssClasses: {
|
||||||
|
default: '',
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
chartOptions: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
chartData() {
|
||||||
|
return {
|
||||||
|
labels: this.stats.map(stat => time(stat.timestamp)),
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Média do sinal',
|
||||||
|
backgroundColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.secondary
|
||||||
|
: this.$vuetify.theme.themes.dark.secondary,
|
||||||
|
borderColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.secondary
|
||||||
|
: this.$vuetify.theme.themes.dark.secondary,
|
||||||
|
borderWidth: 1,
|
||||||
|
data: this.stats.map(stat => stat.avgSignalStrength)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pior sinal',
|
||||||
|
backgroundColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.error
|
||||||
|
: this.$vuetify.theme.themes.dark.error,
|
||||||
|
borderColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.error
|
||||||
|
: this.$vuetify.theme.themes.dark.error,
|
||||||
|
borderWidth: 1,
|
||||||
|
data: this.stats.map(stat => stat.minSignalStrength)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Melhor sinal',
|
||||||
|
backgroundColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.success
|
||||||
|
: this.$vuetify.theme.themes.dark.success,
|
||||||
|
borderColor: this.$vuetify.theme.isDark
|
||||||
|
? this.$vuetify.theme.themes.light.success
|
||||||
|
: this.$vuetify.theme.themes.dark.success,
|
||||||
|
borderWidth: 1,
|
||||||
|
data: this.stats.map(stat => stat.maxSignalStrength)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
|
@ -41,6 +41,17 @@
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
<v-container fluid>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<AccessPointClientsChart :stats="accessPoint.stats" />
|
||||||
|
</v-col>
|
||||||
|
<v-col>
|
||||||
|
<AccessPointSignalStrengthChart :stats="accessPoint.stats" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
<v-divider />
|
||||||
<AccessPointClientsDataTable
|
<AccessPointClientsDataTable
|
||||||
:wifi-devices="accessPoint.wifiDevices"
|
:wifi-devices="accessPoint.wifiDevices"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
@ -65,10 +76,17 @@ import gql from 'graphql-tag'
|
||||||
|
|
||||||
import ApIcon from '../../components/ApIcon.vue'
|
import ApIcon from '../../components/ApIcon.vue'
|
||||||
import AccessPointClientsDataTable from '../../components/DataTables/AccessPointClientsDataTable.vue'
|
import AccessPointClientsDataTable from '../../components/DataTables/AccessPointClientsDataTable.vue'
|
||||||
|
import AccessPointClientsChart from '../../components/Charts/AccessPointClientsChart.vue'
|
||||||
|
import AccessPointSignalStrengthChart from '../../components/Charts/AccessPointSignalStrengthChart.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SingleAccessPoint',
|
name: 'SingleAccessPoint',
|
||||||
components: { ApIcon, AccessPointClientsDataTable },
|
components: {
|
||||||
|
ApIcon,
|
||||||
|
AccessPointClientsDataTable,
|
||||||
|
AccessPointClientsChart,
|
||||||
|
AccessPointSignalStrengthChart
|
||||||
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
showDialog: true,
|
showDialog: true,
|
||||||
filter: ''
|
filter: ''
|
||||||
|
@ -99,6 +117,19 @@ export default {
|
||||||
controller
|
controller
|
||||||
notes
|
notes
|
||||||
updatedAt
|
updatedAt
|
||||||
|
|
||||||
|
stats(take: 100) {
|
||||||
|
id
|
||||||
|
timestamp
|
||||||
|
clients
|
||||||
|
avgSignalStrength
|
||||||
|
minSignalStrength
|
||||||
|
maxSignalStrength
|
||||||
|
avgClientUptime
|
||||||
|
maxClientUptime
|
||||||
|
avgUsage
|
||||||
|
}
|
||||||
|
|
||||||
wifiDevices {
|
wifiDevices {
|
||||||
id
|
id
|
||||||
hostname
|
hostname
|
||||||
|
@ -112,6 +143,7 @@ export default {
|
||||||
protocol
|
protocol
|
||||||
speed
|
speed
|
||||||
usage
|
usage
|
||||||
|
|
||||||
user {
|
user {
|
||||||
displayName
|
displayName
|
||||||
sAMAccountName
|
sAMAccountName
|
||||||
|
|
Loading…
Reference in New Issue
Block a user