Improve restart from UI

This commit is contained in:
ElMoribond 2021-07-14 14:22:35 +02:00
parent 50f0c05e69
commit 870b2f4919
6 changed files with 74 additions and 37 deletions

View File

@ -90,7 +90,7 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics):
client.publish(state_topic, payload, retain=True)
def on_restart_command(client, userdata, message):
restart_frigate()
restart_frigate(client, mqtt_config.topic_prefix)
def on_connect(client, userdata, flags, rc):
threading.current_thread().name = "mqtt"

View File

@ -519,8 +519,15 @@ def clipped(obj, frame_shape):
return False
def restart_frigate():
os.kill(os.getpid(), signal.SIGTERM)
def restart_frigate(mqtt_client, topic_prefix, from_ui = 1):
def on_publish(client,userdata,result):
time.sleep(0.67)
logger.info("Restart requested.")
os.kill(os.getpid(), signal.SIGTERM)
mqtt_client.on_publish = on_publish
mqtt_client.publish(f"{topic_prefix}/restarted", int(from_ui))
class EventsPerSecond:

View File

@ -6,17 +6,14 @@ import AutoAwesomeIcon from './icons/AutoAwesome';
import LightModeIcon from './icons/LightMode';
import DarkModeIcon from './icons/DarkMode';
import FrigateRestartIcon from './icons/FrigateRestart';
import Dialog from './components/Dialog';
import DialogRestart from './components/DialogRestart';
import { useDarkMode } from './context';
import { useCallback, useRef, useState } from 'preact/hooks';
import { useRestart } from './api/mqtt';
export default function AppBar() {
const [showMoreMenu, setShowMoreMenu] = useState(false);
const [showDialog, setShowDialog] = useState(false);
const [showDialogWait, setShowDialogWait] = useState(false);
const [showDialogRestart, setShowDialogRestart] = useState(false);
const { setDarkMode } = useDarkMode();
const { send: sendRestart } = useRestart();
const handleSelectDarkMode = useCallback(
(value, label) => {
@ -36,16 +33,6 @@ export default function AppBar() {
setShowMoreMenu(false);
}, [setShowMoreMenu]);
const handleClickRestartDialog = useCallback(() => {
setShowDialog(false);
setShowDialogWait(true);
sendRestart();
}, [setShowDialog]); // eslint-disable-line react-hooks/exhaustive-deps
const handleDismissRestartDialog = useCallback(() => {
setShowDialog(false);
}, [setShowDialog]);
const handleRestart = useCallback(() => {
setShowMoreMenu(false);
setShowDialog(true);
@ -64,23 +51,7 @@ export default function AppBar() {
<MenuItem icon={FrigateRestartIcon} label="Restart Frigate" onSelect={handleRestart} />
</Menu>
) : null},
{showDialog ? (
<Dialog
onDismiss={handleDismissRestartDialog}
title="Restart Frigate"
text="Are you sure?"
actions={[
{ text: 'Yes', color: 'red', onClick: handleClickRestartDialog },
{ text: 'Cancel', onClick: handleDismissRestartDialog },
]}
/>
) : null},
{showDialogWait ? (
<Dialog
title="Restart in progress"
text="Please wait a few seconds for the restart to complete before reloading the page."
/>
) : null}
<DialogRestart show={showDialogRestart} setShow={setShowDialogRestart} />
</Fragment>
);
}

View File

@ -124,6 +124,6 @@ export function useRestart() {
value: { payload },
send,
connected,
} = useMqtt('restart', 'restart');
} = useMqtt('restarted', 'restart');
return { payload, send, connected };
}

View File

@ -28,7 +28,7 @@ export default function Dialog({ actions = [], portalRootID = 'dialogs', title,
}`}
>
<div className="p-4">
<Heading size="lg">{title}</Heading>
<Heading size="lg" className="mb-4">{title}</Heading>
<p>{text}</p>
</div>
<div className="p-2 flex justify-start flex-row-reverse space-x-2">

View File

@ -0,0 +1,59 @@
import { h, Fragment } from 'preact';
import Dialog from './Dialog';
import { useCallback, useEffect, useState } from 'preact/hooks';
import { useRestart } from '../api/mqtt';
export default function DialogRestart({ show, setShow }) {
const { payload: detectRestarted = null, send: sendRestart } = useRestart();
const [dialogTitle, setDialogTitle] = useState('Restart in progress');
useEffect(() => {
if (detectRestarted != null && Number.isInteger(detectRestarted)) {
if (!detectRestarted)
setDialogTitle('Server-initiated startup');
setShow(false);
}
}, [detectRestarted]); // eslint-disable-line react-hooks/exhaustive-deps
const waitPlease = async () => {
const delay = ms => new Promise(res => setTimeout(res, ms));
await delay(3456);
/* eslint-disable no-constant-condition */
while (true) {
try {
const response = await fetch('/api/config', { method: 'GET' });
if (await response.status === 200)
window.location.reload();
}
catch (e) {}
await delay(987);
}
};
const handleClick = useCallback(() => {
sendRestart();
setShow(false);
waitPlease();
}, [show]); // eslint-disable-line react-hooks/exhaustive-deps
const handleDismiss = useCallback(() => {
setShow(false);
}, [show]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<Fragment>
{show ? (
<Dialog
onDismiss={handleDismiss}
title="Restart Frigate"
text="Are you sure?"
actions={[
{ text: 'Yes', color: 'red', onClick: handleClick },
{ text: 'Cancel', onClick: handleDismiss } ]}
/>
) : detectRestarted != null && (
<Dialog title={dialogTitle} text="This page should refresh as soon as the server is up and running…" />
)}
</Fragment>
);
}