diff --git a/src/openflexure_microscope_server/things/settings_manager.py b/src/openflexure_microscope_server/things/settings_manager.py
index 13592691..24ed8052 100644
--- a/src/openflexure_microscope_server/things/settings_manager.py
+++ b/src/openflexure_microscope_server/things/settings_manager.py
@@ -7,12 +7,21 @@ the server.
"""
from collections.abc import Mapping
from socket import gethostname
-from typing import Any, MutableMapping, Optional, Sequence
+from typing import Annotated, Any, MutableMapping, Optional, Sequence
from uuid import UUID, uuid4
-from fastapi import HTTPException
+from fastapi import Depends, HTTPException, Request
from labthings_fastapi.dependencies.metadata import GetThingStates
from labthings_fastapi.thing import Thing
from labthings_fastapi.decorators import thing_action, thing_property
+from labthings_fastapi.thing_server import find_thing_server, ThingServer
+from labthings_fastapi.dependencies.invocation import InvocationLogger
+
+
+def thing_server_from_request(request: Request) -> ThingServer:
+ return find_thing_server(request.app)
+
+
+ThingServerDep = Annotated[ThingServer, Depends(thing_server_from_request)]
def recursive_update(old_dict: MutableMapping, update: Mapping):
@@ -122,4 +131,31 @@ class SettingsManager(Thing):
subdict[kl[-1]] = v
except KeyError:
continue
- return state
\ No newline at end of file
+ return state
+
+ @thing_action
+ def save_all_thing_settings(self, thing_server: ThingServerDep, logger: InvocationLogger) -> None:
+ """Ensure all the Things sync their settings to disk.
+
+ Normally, each Thing has a `thing_settings` attribute that can be
+ used to save settings. That dictionary is saved to a JSON file
+ when the server shuts down cleanly.
+
+ This action causes all the `thing_settings` dictionaries to be
+ saved to files immediately, meaning that settings will not be
+ lost in the event of a server crash, power outage, etc.
+ """
+ for name, thing in thing_server.things.items():
+ try:
+ if thing._labthings_thing_settings:
+ thing._labthings_thing_settings.write_to_file()
+ logger.info(f"Wrote {name} settings to disk.")
+ except PermissionError:
+ logger.warning(
+ f"Could not write {name} settings to disk: permission error."
+ )
+ except FileNotFoundError:
+ logger.warning(
+ f"Could not write {name} settings, folder not found"
+ )
+
diff --git a/webapp/src/components/tabContentComponents/settingsContent.vue b/webapp/src/components/tabContentComponents/settingsContent.vue
index d8ea2e05..3889ecfd 100644
--- a/webapp/src/components/tabContentComponents/settingsContent.vue
+++ b/webapp/src/components/tabContentComponents/settingsContent.vue
@@ -71,6 +71,11 @@
+