Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,32 @@
<q-badge
rounded
align="middle"
:color="connected ? 'positive' : 'negative'"
:color="stateDisplay.color"
class="non-selectable"
>
<q-icon :name="connected ? 'link' : 'link_off'" size="sm">
<q-tooltip v-if="connected">Verbindung hergestellt</q-tooltip>
<q-tooltip v-else>Verbindung getrennt</q-tooltip>
<q-icon :name="stateDisplay.icon" size="sm">
<q-tooltip>{{ stateDisplay.tooltip }}</q-tooltip>
</q-icon>
</q-badge>
</div>
<q-dialog v-model="showModal" persistent>
<q-card>
<q-card-section class="row items-center">
<q-avatar icon="link_off" color="negative" text-color="white" />
<span class="text-h6 q-ml-sm">Verbindung getrennt!</span>
<q-avatar
:icon="stateDisplay.icon"
:color="stateDisplay.color"
text-color="white"
/>
<span class="text-h6 q-ml-sm">{{ stateDisplay.title }}</span>
</q-card-section>
<q-card-section class="row">
<q-card-section v-if="connectionState === 'connecting'" class="row">
Die Verbindung zur openWB wird hergestellt.<br />
Bitte warten...
</q-card-section>
<q-card-section
v-else-if="connectionState === 'disconnected'"
class="row"
>
Die Verbindung zur openWB ist unterbrochen.<br />
Es wird versucht, die Verbindung wieder herzustellen...
</q-card-section>
Expand All @@ -27,32 +37,119 @@
</template>

<script setup lang="ts">
import { computed, watch, ref } from 'vue';
import { computed, watch, ref, onBeforeUnmount } from 'vue';
import { useMqttStore } from 'src/stores/mqtt-store';

// delay before showing the connecting dialog, prevents flickering on fast connects
const CONNECTING_DIALOG_DELAY = 1000;
// time to wait for a connection before showing the disconnected warning
const CONNECTING_GRACE_PERIOD = 10000;

const mqttStore = useMqttStore();

const connected = computed(() => mqttStore.mqttClientConnected);
const dialogDelayPassed = ref(false);
const gracePeriodExpired = ref(false);

const showIcon = ref(!connected.value);
const iconTimeout = ref<ReturnType<typeof setTimeout> | null>(null);
const showModal = computed(() => !connected.value);
const connectionState = computed(() => {
if (connected.value) {
return 'connected';
}
return gracePeriodExpired.value ? 'disconnected' : 'connecting';
});

watch(connected, (newValue) => {
if (!newValue) {
console.warn('MQTT-Verbindung verloren!');
showIcon.value = true;
if (iconTimeout.value) {
clearTimeout(iconTimeout.value);
}
} else {
console.info('MQTT-Verbindung wiederhergestellt!');
if (iconTimeout.value) {
clearTimeout(iconTimeout.value);
const stateDisplay = computed(() => {
switch (connectionState.value) {
case 'connected':
return {
color: 'positive',
icon: 'link',
tooltip: 'Verbindung hergestellt',
title: 'Verbindung hergestellt',
};
case 'connecting':
return {
color: 'grey',
icon: 'hourglass_empty',
tooltip: 'Verbindung wird aufgebaut',
title: 'Verbindung wird aufgebaut',
};
default:
return {
color: 'negative',
icon: 'link_off',
tooltip: 'Verbindung getrennt',
title: 'Verbindung getrennt!',
};
}
});

const showIcon = ref(false);
const iconHideTimer = ref<ReturnType<typeof setTimeout> | null>(null);
const dialogDelayTimer = ref<ReturnType<typeof setTimeout> | null>(null);
const gracePeriodTimer = ref<ReturnType<typeof setTimeout> | null>(null);
const showModal = computed(
() =>
connectionState.value === 'disconnected' ||
(connectionState.value === 'connecting' && dialogDelayPassed.value),
);

const clearConnectingTimers = () => {
if (dialogDelayTimer.value) {
clearTimeout(dialogDelayTimer.value);
dialogDelayTimer.value = null;
}
if (gracePeriodTimer.value) {
clearTimeout(gracePeriodTimer.value);
gracePeriodTimer.value = null;
}
};

const startConnectingTimers = () => {
clearConnectingTimers();
dialogDelayPassed.value = false;
gracePeriodExpired.value = false;
dialogDelayTimer.value = setTimeout(() => {
dialogDelayPassed.value = true;
}, CONNECTING_DIALOG_DELAY);
gracePeriodTimer.value = setTimeout(() => {
console.warn('MQTT-Verbindung konnte nicht hergestellt werden!');
gracePeriodExpired.value = true;
}, CONNECTING_GRACE_PERIOD);
Comment thread
benderl marked this conversation as resolved.
};

watch(
connected,
(newValue, oldValue) => {
if (!newValue) {
if (oldValue !== undefined) {
console.warn('MQTT-Verbindung verloren!');
}
showIcon.value = true;
if (iconHideTimer.value) {
clearTimeout(iconHideTimer.value);
}
startConnectingTimers();
} else if (oldValue !== undefined) {
console.info('MQTT-Verbindung wiederhergestellt!');
clearConnectingTimers();
dialogDelayPassed.value = false;
gracePeriodExpired.value = false;
if (iconHideTimer.value) {
clearTimeout(iconHideTimer.value);
}
iconHideTimer.value = setTimeout(() => {
showIcon.value = false;
}, 5000);
}
iconTimeout.value = setTimeout(() => {
showIcon.value = false;
}, 5000);
},
{ immediate: true },
);

onBeforeUnmount(() => {
clearConnectingTimers();
if (iconHideTimer.value) {
clearTimeout(iconHideTimer.value);
}
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import { ref, computed, watch } from 'vue';
import { useQuasar, QInput } from 'quasar';
import { useMqttStore } from 'src/stores/mqtt-store';

Expand Down Expand Up @@ -378,22 +378,15 @@ const resetPassword = () => {
});
};

watch(anonymousAccessAllowed, (newValue) => {
if (userManagementActive.value && !newValue && !loggedIn.value) {
showLoginDialog.value = true;
} else {
showLoginDialog.value = false;
}
});

onMounted(() => {
if (
connected.value &&
userManagementActive.value &&
!anonymousAccessAllowed.value &&
!loggedIn.value
) {
showLoginDialog.value = true;
}
});
// security topics are received after connecting, re-check whenever one of them arrives
watch(
[userManagementActive, anonymousAccessAllowed],
() => {
showLoginDialog.value =
userManagementActive.value &&
!anonymousAccessAllowed.value &&
!loggedIn.value;
Comment on lines +382 to +388
},
{ immediate: true },
);
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -783,16 +783,12 @@ export const useMqttStore = defineStore('mqtt', () => {

/**
* Check if user management is active
* Defaults to true if the value is not set as this may be due to insufficient permissions
* Returns false until the retained value is received, the topic is readable for all clients (including anonymous)
* @returns boolean
*/
const userManagementActive: ComputedRef<boolean> = computed(() => {
return (
getValue.value(
'openWB/system/security/user_management_active',
undefined,
true,
) === true
getValue.value('openWB/system/security/user_management_active') === true
);
});

Expand Down
Loading