mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-30 02:31:40 +00:00
Fix static IP and network settings on Pi
This commit is contained in:
@@ -4,34 +4,33 @@
|
||||
ref="form"
|
||||
v-model="valid"
|
||||
>
|
||||
<CVSwitch
|
||||
v-model="runNTServer"
|
||||
name="Run NetworkTables Server"
|
||||
tooltip="If enabled, this device will create a NT server. This is useful for home debugging, but should be disabled on-robot."
|
||||
/>
|
||||
<CVnumberinput
|
||||
v-model="settings.teamNumber"
|
||||
v-model="teamNumber"
|
||||
:disabled="settings.runNTServer"
|
||||
name="Team Number"
|
||||
:rules="[v => (v > 0) || 'Team number must be greater than zero', v => (v < 10000) || 'Team number must have fewer than five digits']"
|
||||
class="mb-4"
|
||||
/>
|
||||
<CVSwitch
|
||||
v-model="settings.runNTServer"
|
||||
name="Run NetworkTables Server"
|
||||
tooltip="If enabled, this device will create a NT server. This is useful for home debugging, but should be disabled on-robot."
|
||||
<CVradio
|
||||
v-model="connectionType"
|
||||
:list="['DHCP','Static']"
|
||||
:disabled="!$store.state.settings.networkSettings.supported"
|
||||
/>
|
||||
<template v-if="$store.state.settings.networkSettings.supported">
|
||||
<CVradio
|
||||
v-model="settings.connectionType"
|
||||
:list="['DHCP','Static']"
|
||||
<template v-if="!isDHCP">
|
||||
<CVinput
|
||||
v-model="staticIp"
|
||||
:input-cols="inputCols"
|
||||
:rules="[v => isIPv4(v) || 'Invalid IPv4 address']"
|
||||
name="IP"
|
||||
/>
|
||||
<template v-if="!isDHCP">
|
||||
<CVinput
|
||||
v-model="settings.staticIp"
|
||||
:input-cols="inputCols"
|
||||
:rules="[v => isIPv4(v) || 'Invalid IPv4 address']"
|
||||
name="IP"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<CVinput
|
||||
v-model="settings.hostname"
|
||||
v-model="hostname"
|
||||
:input-cols="inputCols"
|
||||
:rules="[v => isHostname(v) || 'Invalid hostname']"
|
||||
name="Hostname"
|
||||
@@ -49,94 +48,135 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVnumberinput from '../../components/common/cv-number-input'
|
||||
import CVradio from '../../components/common/cv-radio'
|
||||
import CVinput from '../../components/common/cv-input'
|
||||
import CVSwitch from "@/components/common/cv-switch";
|
||||
import CVnumberinput from '../../components/common/cv-number-input'
|
||||
import CVradio from '../../components/common/cv-radio'
|
||||
import CVinput from '../../components/common/cv-input'
|
||||
import CVSwitch from "@/components/common/cv-switch";
|
||||
|
||||
// https://stackoverflow.com/a/17871737
|
||||
const ipv4Regex = /^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$/;
|
||||
// https://stackoverflow.com/a/18494710
|
||||
const hostnameRegex = /^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)+(\.([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*))*$/;
|
||||
// https://stackoverflow.com/a/17871737
|
||||
const ipv4Regex = /^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$/;
|
||||
// https://stackoverflow.com/a/18494710
|
||||
const hostnameRegex = /^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)+(\.([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*))*$/;
|
||||
|
||||
export default {
|
||||
name: 'Networking',
|
||||
components: {
|
||||
CVSwitch,
|
||||
CVnumberinput,
|
||||
CVradio,
|
||||
CVinput
|
||||
export default {
|
||||
name: 'Networking',
|
||||
components: {
|
||||
CVSwitch,
|
||||
CVnumberinput,
|
||||
CVradio,
|
||||
CVinput
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
file: undefined,
|
||||
snackbar: {
|
||||
color: "success",
|
||||
text: ""
|
||||
},
|
||||
snack: false,
|
||||
isLoading: false,
|
||||
valid: true, // Are all settings valid
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inputCols() {
|
||||
return this.$vuetify.breakpoint.smAndUp ? 10 : 7;
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
file: undefined,
|
||||
snackbar: {
|
||||
color: "success",
|
||||
text: ""
|
||||
},
|
||||
snack: false,
|
||||
isLoading: false,
|
||||
valid: true, // Are all settings valid
|
||||
isDHCP() {
|
||||
return this.settings.connectionType === 0;
|
||||
},
|
||||
settings() {
|
||||
return this.$store.state.settings.networkSettings;
|
||||
},
|
||||
teamNumber: {
|
||||
get() {
|
||||
return this.settings.teamNumber
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('mutateNetworkSettings', {['teamNumber']: value});
|
||||
}
|
||||
},
|
||||
runNTServer: {
|
||||
get() {
|
||||
return this.settings.runNTServer
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('mutateNetworkSettings', {['runNTServer']: value});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inputCols() {
|
||||
return this.$vuetify.breakpoint.smAndUp ? 10 : 7;
|
||||
connectionType: {
|
||||
get() {
|
||||
return this.settings.connectionType
|
||||
},
|
||||
isDHCP() {
|
||||
return this.settings.connectionType === 0;
|
||||
},
|
||||
settings() {
|
||||
return this.$store.state.settings.networkSettings;
|
||||
set(value) {
|
||||
this.$store.commit('mutateNetworkSettings', {['connectionType']: value});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isIPv4(v) {
|
||||
return ipv4Regex.test(v);
|
||||
staticIp: {
|
||||
get() {
|
||||
return this.settings.staticIp
|
||||
},
|
||||
isHostname(v) {
|
||||
return hostnameRegex.test(v);
|
||||
set(value) {
|
||||
this.$store.commit('mutateNetworkSettings', {['staticIp']: value});
|
||||
}
|
||||
},
|
||||
hostname: {
|
||||
get() {
|
||||
return this.settings.hostname
|
||||
},
|
||||
// https://www.freesoft.org/CIE/Course/Subnet/6.htm
|
||||
// https://stackoverflow.com/a/13957228
|
||||
isSubnetMask(v) {
|
||||
// Has to be valid IPv4 so we'll start here
|
||||
if (!this.isIPv4(v)) return false;
|
||||
set(value) {
|
||||
this.$store.commit('mutateNetworkSettings', {['hostname']: value});
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isIPv4(v) {
|
||||
return ipv4Regex.test(v);
|
||||
},
|
||||
isHostname(v) {
|
||||
return hostnameRegex.test(v);
|
||||
},
|
||||
// https://www.freesoft.org/CIE/Course/Subnet/6.htm
|
||||
// https://stackoverflow.com/a/13957228
|
||||
isSubnetMask(v) {
|
||||
// Has to be valid IPv4 so we'll start here
|
||||
if (!this.isIPv4(v)) return false;
|
||||
|
||||
let octets = v.split(".").map(it => Number(it));
|
||||
let restAreOnes = false;
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
let octets = v.split(".").map(it => Number(it));
|
||||
let restAreOnes = false;
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
let bitValue = (octets[i] >>> j & 1) == 1;
|
||||
if (restAreOnes && !bitValue)
|
||||
return false;
|
||||
restAreOnes = bitValue;
|
||||
let bitValue = (octets[i] >>> j & 1) == 1;
|
||||
if (restAreOnes && !bitValue)
|
||||
return false;
|
||||
restAreOnes = bitValue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
sendGeneralSettings() {
|
||||
this.axios.post("http://" + this.$address + "/api/settings/general", this.settings).then(
|
||||
function (response) {
|
||||
if (response.status === 200) {
|
||||
this.snackbar = {
|
||||
color: "success",
|
||||
text: "Settings updated successfully"
|
||||
};
|
||||
this.snack = true;
|
||||
}
|
||||
},
|
||||
function (error) {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
sendGeneralSettings() {
|
||||
this.axios.post("http://" + this.$address + "/api/settings/general", this.settings).then(
|
||||
function (response) {
|
||||
if (response.status === 200) {
|
||||
this.snackbar = {
|
||||
color: "error",
|
||||
text: (error.response || {data: "Couldn't save settings"}).data
|
||||
color: "success",
|
||||
text: "Settings updated successfully"
|
||||
};
|
||||
this.snack = true;
|
||||
}
|
||||
)
|
||||
},
|
||||
},
|
||||
function (error) {
|
||||
this.snackbar = {
|
||||
color: "error",
|
||||
text: (error.response || {data: "Couldn't save settings"}).data
|
||||
};
|
||||
this.snack = true;
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
Reference in New Issue
Block a user