Skip to content

Commit

Permalink
frontend: Add modem disable functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
JoaoMario109 committed Dec 10, 2024
1 parent c5258c9 commit e9a4548
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 35 deletions.
59 changes: 40 additions & 19 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@back="onBack"
@reboot="onModemReboot"
@reset="onModemReset"
@disable="onModemDisable"
/>
<v-container
v-else
Expand Down Expand Up @@ -73,32 +74,44 @@ const fetchAvailableModems = async () => {
}
};
const initComponent = async (delay: number = 500, title: string = 'Fetching available modems') => {
const initLoad = (title: string = 'Fetching available modems') => {
fetchAvailableModemTask.stop();
selectedModem.value = null;
availableModems.value = [];
opLoading.value = true;
opDescription.value = title;
await fetchAvailableModems();
}
/** Since this fetch is USUALLY fast we simulate a delay to avoid glitch */
await sleep(delay);
const finishLoad = () => {
opLoading.value = false;
fetchAvailableModemTask.resume();
};
}
const initRebootComponent = async () => {
selectedModem.value = null;
availableModems.value = [];
initComponent(10000, "Rebooting modem");
};
const initComponent = async () => {
await initLoad();
await fetchAvailableModems();
/** Since this fetch is USUALLY fast we simulate a delay to avoid glitch */
await sleep(500);
await finishLoad();
}
const rebootModem = async (action: Promise<void>, title: string = 'Rebooting modem') => {
await initLoad(title);
await action;
await sleep(15000);
await fetchAvailableModems();
await finishLoad();
}
/** Callbacks */
const onModemSelected = (modem: ModemDevice) => {
selectedModem.value = modem;
};
const onBack = () => {
selectedModem.value = null;
initComponent();
const onBack = async () => {
await initComponent();
};
const onModemReboot = async () => {
Expand All @@ -107,9 +120,7 @@ const onModemReboot = async () => {
}
try {
await ModemManager.rebootById(selectedModem.value?.id);
initRebootComponent();
rebootModem(ModemManager.rebootById(selectedModem.value?.id));
} catch (error) {
opError.value = String((error as any)?.message);
}
Expand All @@ -121,9 +132,19 @@ const onModemReset = async () => {
}
try {
await ModemManager.resetById(selectedModem.value?.id);
rebootModem(ModemManager.resetById(selectedModem.value?.id), 'Resetting modem');
} catch (error) {
opError.value = String((error as any)?.message);
}
};
const onModemDisable = async () => {
if (selectedModem.value === null) {
return;
}
initRebootComponent();
try {
rebootModem(ModemManager.disableById(selectedModem.value?.id), 'Disabling modem');
} catch (error) {
opError.value = String((error as any)?.message);
}
Expand All @@ -134,6 +155,6 @@ const fetchAvailableModemTask = new OneMoreTime({ delay: 10000, disposeWith: thi
/** Hooks */
onMounted(async () => {
initComponent();
await initComponent();
});
</script>
12 changes: 10 additions & 2 deletions frontend/src/components/device/DeviceDetailsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
<ModemOperatorDetails :modem="modem" />
</v-col>
<v-col cols="12" md="8" class="device-col">
<ModemDeviceDetails :modem="modem" @reset="onReset"/>
<ModemDeviceDetails
:modem="modem"
@reset="onReset"
@reboot="onReboot"
/>
</v-col>
</v-container>
</template>
Expand All @@ -20,12 +24,16 @@ import ModemDeviceDetails from './ModemDeviceDetails.vue';
defineProps<{
modem: ModemDevice;
}>();
const emit = defineEmits<(event: 'reset') => void>();
const emit = defineEmits<(event: 'reset' | 'reboot') => void>();
/** Callbacks */
const onReset = () => {
emit('reset');
};
const onReboot = () => {
emit('reboot');
};
</script>

<style>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/device/ModemDeviceDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</v-col>
<v-col cols="12" md="2" class="details-column reset-column">
<v-btn color="primary" @click="onConsole">Console</v-btn>
<v-btn color="primary" @click="onReboot">Reboot</v-btn>
<v-btn color="warning" @click="onReset">Reset</v-btn>
</v-col>
</v-row>
Expand Down Expand Up @@ -87,7 +88,7 @@ import SpinningLogo from '@/components/common/SpinningLogo.vue';
const props = defineProps<{
modem: ModemDevice;
}>();
const emit = defineEmits<(event: 'reset') => void>();
const emit = defineEmits<(event: 'reset' | 'reboot') => void>();
const ansi = new AnsiUp();
Expand Down Expand Up @@ -120,6 +121,10 @@ const onReset = () => {
showResetDialog.value = true;
};
const onReboot = () => {
emit('reboot');
};
const onConsole = () => {
showConsoleDialog.value = true;
};
Expand Down
27 changes: 25 additions & 2 deletions frontend/src/services/ModemManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ModemDevice,
ModemDeviceDetails,
ModemPosition,
ModemFunctionality,
ModemSIMStatus,
ModemSignalQuality,
NearbyCellTower,
Expand All @@ -20,7 +21,7 @@ const MODEM_MANAGER_V1_API = `/v1.0`

const api = axios.create({
baseURL: MODEM_MANAGER_V1_API,
timeout: 15000,
timeout: 25000,
})

/**
Expand Down Expand Up @@ -62,6 +63,16 @@ export async function fetchCellInfoById(modemId: string): Promise<ModemCellInfo>
return response.data as ModemCellInfo
}

/**
* Get current modem functionality by id.
* @param {string} modemId - Modem ID
* @returns {Promise<ModemFunctionality>}
*/
export async function fetchFunctionalityById(modemId: string): Promise<ModemFunctionality> {
const response = await api.get(`/modem/${modemId}/functionality`)
return response.data as ModemFunctionality
}

/**
* Execute an AT command in a modem by modem id.
* @param {string} modemId - Modem ID
Expand All @@ -84,6 +95,16 @@ export async function rebootById(modemId: string): Promise<void> {
await api.post(`/modem/${modemId}/reboot`)
}


/**
* Disable a modem by id.
* @param {string} modemId - Modem ID
* @returns {Promise<void>}
*/
export async function disableById(modemId: string): Promise<void> {
await api.post(`/modem/${modemId}/disable`)
}

/**
* Reset a modem to factory settings by id.
* @param {string} modemId - Modem ID
Expand Down Expand Up @@ -215,12 +236,14 @@ export async function fetchNearbyCellsCoordinates(

export default {
commandById,
disableById,
fetch,
fetchById,
fetchCellCoordinates,
fetchCellInfoById,
fetchClockById,
fetchDataUsageById,
fetchFunctionalityById,
fetchNearbyCellsCoordinates,
fetchOperatorInfoById,
fetchPDPInfoById,
Expand All @@ -233,4 +256,4 @@ export default {
setAPNByProfileById,
setDataUsageControlById,
setUSBModeById,
}
};
6 changes: 6 additions & 0 deletions frontend/src/types/ModemManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export enum ModemSIMStatus {
UNKNOWN = "2",
}

export enum ModemFunctionality {
MINIMAL = "0",
FULL = "1",
BLOCKED = "4",
}

export interface DataUsageControls {
data_control_enabled: boolean
// Data limit in bytes, default is 2GB
Expand Down
48 changes: 37 additions & 11 deletions frontend/src/views/ModemDetailsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
</div>

<div class="action-buttons d-flex justify-md-end justify-xs-start">
<v-btn
class="ma-2"
color="primary"
@click="onReboot"
>
Reboot
</v-btn>
<v-switch
v-if="modemEnabled !== null"
v-model="modemEnabled"
label="Enable Modem"
:color="modemEnabled ? 'primary' : 'grey'"
@change="onModemEnabledToggle"
/>
</div>
</v-row>

Expand All @@ -54,7 +54,11 @@
<v-card-text>
<v-tabs-window v-model="selectedTab">
<v-tabs-window-item value="device">
<DeviceDetailsTab :modem="props.modem" @reset="onReset" />
<DeviceDetailsTab
:modem="props.modem"
@reset="onReset"
@reboot="onReboot"
/>
</v-tabs-window-item>

<v-tabs-window-item value="network">
Expand All @@ -77,12 +81,12 @@
</template>

<script setup lang="ts">
import { ref, defineProps } from 'vue';
import { ref, defineProps, onMounted } from 'vue';
import defaultThumbnail from "@/assets/thumbs/unknown.svg";
import ModemManager from '@/services/ModemManager';
import { ModemDevice, ModemClockDetails } from '@/types/ModemManager';
import { ModemDevice, ModemClockDetails, ModemFunctionality } from '@/types/ModemManager';
import NetworkDetailsTab from '@/components/network/NetworkDetailsTab.vue';
import DeviceDetailsTab from '@/components/device/DeviceDetailsTab.vue';
Expand All @@ -95,12 +99,13 @@ import { OneMoreTime } from '@/one-more-time';
const props = defineProps<{
modem: ModemDevice;
}>();
const emit = defineEmits<(event: 'reboot' | 'back' | 'reset') => void>();
const emit = defineEmits<(event: 'reboot' | 'back' | 'reset' | 'disable') => void>();
/** States */
const selectedTab = ref<number>(0);
const currentClockGmtOffset = ref<number>(0);
const currentClock = ref<number | null>(null);
const modemEnabled = ref<boolean | null>(null);
/** Utils */
const clockToUnix = (clock: ModemClockDetails) => {
Expand Down Expand Up @@ -129,6 +134,16 @@ const fetchClock = async () => {
}
};
const fetchFunctionality = async () => {
try {
const func = await ModemManager.fetchFunctionalityById(props.modem.id);
modemEnabled.value = func != ModemFunctionality.BLOCKED;
} catch (error) {
console.error("Unable to fetch functionality details from modem device", error);
}
};
const incrementClockLocally = () => {
if (currentClock.value) {
currentClock.value += 1000;
Expand All @@ -151,6 +166,17 @@ const onBack = () => {
const onReset = () => {
emit('reset');
};
const onModemEnabledToggle = () => {
if (modemEnabled.value) {
emit('reboot');
} else {
emit('disable');
}
};
/** Hooks */
onMounted(fetchFunctionality);
</script>

<style scoped>
Expand Down

0 comments on commit e9a4548

Please sign in to comment.