[2026-07-02 11:02:37,670] [INFO] <openflexure_microscope_server.logging> OFM server root logger has been set up at INFO level
[2026-07-02 11:02:37,702] [INFO] <labthings_fastapi.things.camera> Starting picamera __init__
[2026-07-02 11:02:37,713] [INFO] <labthings_fastapi.things.camera> Getting exposure time. Cached value 500.
[2026-07-02 11:02:37,714] [INFO] <labthings_fastapi.things.camera> Returning 500
[2026-07-02 11:02:37,724] [INFO] <labthings_fastapi.things.camera> stopping __init__
[2026-07-02 11:02:37,748] [WARNING] <labthings_fastapi.things.camera> None is not a valid background detector name.
[2026-07-02 11:02:37,749] [INFO] <labthings_fastapi.things.camera> Setting exposure time to 500, previous was 500.
[2026-07-02 11:02:37,749] [INFO] <labthings_fastapi.things.camera> Current streaming status: False
[2026-07-02 11:02:38,859] [INFO] <uvicorn> Started server process [80579]
[2026-07-02 11:02:38,860] [INFO] <uvicorn> Waiting for application startup.
[2026-07-02 11:02:38,873] [INFO] <labthings_fastapi.things.camera> starting StreamingPiCamera2.__enter__
[2026-07-02 11:02:38,874] [INFO] <labthings_fastapi.things.camera> starting _initialise_picamera
[2026-07-02 11:02:38,877] [INFO] <openflexure_microscope_server.things.camera.picamera> Creating new Picamera2 object
[2026-07-02 11:02:38,930] [INFO] <picamera2.picamera2> Initialization successful.
[2026-07-02 11:02:38,930] [INFO] <picamera2.picamera2> Camera now open.
[2026-07-02 11:02:38,933] [INFO] <labthings_fastapi.things.camera> stopping _initialise_picamera
[2026-07-02 11:02:38,934] [INFO] <labthings_fastapi.things.camera> Getting exposure time. Cached value 500.
[2026-07-02 11:02:38,935] [INFO] <labthings_fastapi.things.camera> Returning 500
[2026-07-02 11:02:38,938] [INFO] <picamera2.picamera2> Camera configuration has been adjusted!
[2026-07-02 11:02:38,941] [INFO] <picamera2.picamera2> Configuration successful!
[2026-07-02 11:02:38,975] [INFO] <openflexure_microscope_server.things.camera.picamera> Starting picamera MJPEG stream...
[2026-07-02 11:02:39,012] [INFO] <picamera2.picamera2> Camera started
[2026-07-02 11:02:39,032] [INFO] <labthings_fastapi.things.camera> stopping StreamingPiCamera2.__enter__
[2026-07-02 11:02:39,033] [INFO] <sangaboard.sangaboard> Initialising ExtensibleSerialInstrument on port None
[2026-07-02 11:02:39,034] [INFO] <sangaboard.extensible_serial_instrument> Updating ESI port settings
[2026-07-02 11:02:39,035] [INFO] <sangaboard.extensible_serial_instrument> Opening ESI connection to port None
[2026-07-02 11:02:39,042] [INFO] <sangaboard.extensible_serial_instrument> Creating serial.Serial instance...
[2026-07-02 11:02:39,043] [INFO] <sangaboard.extensible_serial_instrument> Created Serial<id=0x7f625491b0, open=True>(port='/dev/ttyAMA0', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
[2026-07-02 11:02:39,044] [INFO] <sangaboard.sangaboard> Testing communication to SangaBoard
[2026-07-02 11:02:39,044] [INFO] <sangaboard.sangaboard> Running firmware checks...
[2026-07-02 11:02:39,049] [INFO] <sangaboard.sangaboard> Firmware response: Sangaboard Firmware v1.0.4
[2026-07-02 11:02:39,050] [INFO] <sangaboard.extensible_serial_instrument> Success!
[2026-07-02 11:02:39,051] [INFO] <sangaboard.extensible_serial_instrument> Creating serial.Serial instance...
[2026-07-02 11:02:39,052] [INFO] <sangaboard.extensible_serial_instrument> Created Serial<id=0x7f624e0d90, open=True>(port='/dev/ttyAMA0', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
[2026-07-02 11:02:39,052] [INFO] <sangaboard.sangaboard> Testing communication to SangaBoard
[2026-07-02 11:02:39,055] [INFO] <sangaboard.sangaboard> Running firmware checks...
[2026-07-02 11:02:39,060] [INFO] <sangaboard.sangaboard> Firmware response: Sangaboard Firmware v1.0.4
[2026-07-02 11:02:39,061] [INFO] <sangaboard.extensible_serial_instrument> Opened ESI connection to port None
[2026-07-02 11:02:39,061] [INFO] <sangaboard.sangaboard> Checking valid firmware...
[2026-07-02 11:02:39,061] [INFO] <sangaboard.sangaboard> Running firmware checks...
[2026-07-02 11:02:39,066] [INFO] <sangaboard.sangaboard> Firmware response: Sangaboard Firmware v1.0.4
[2026-07-02 11:02:39,067] [INFO] <sangaboard.sangaboard> Loading modules...
[2026-07-02 11:02:39,083] [INFO] <sangaboard.sangaboard> Enabling backwards-compatible behaviour on new Sangaboard firmware
[2026-07-02 11:02:39,108] [INFO] <uvicorn> Application startup complete.
[2026-07-02 11:02:39,112] [INFO] <uvicorn> Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
Describe the bug
The settings for
openflexure_microscope_server.things.camera.picamera.StreamingPiCameraV2are overwritten with defaults when I runofm restartor otherwise restart the serverTo Reproduce
curl http://localhost:5000/api/v3/camera/exposure_time --request PUT -d 2000curl http://localhost:5000/api/v3/camera/exposure_timesettings/camera/Settings-StreamingPiCameraV2.jsonofm restartcurl http://localhost:5000/api/v3/camera/exposure_timeIt's also possible to observe in the GUI, but this method was easier to use when finding the offending commit.
Expected behaviour
The settings should be remembered across a restart
Additional context
This problem was introduced by #256. The previous merge commit does not exhibit the problem.
This is not simply a blanket failure to remember settings. That would have been caught by unit tests. Other Things on the OpenFlexure server (e.g. the Camera Stage Mapping thing) do correctly remember their settings. The camera hardware is a bit badly-behaved when it comes to settings, so the camera Thing has some complicated logic embedded in various functional settings:
My guess is that the problem appeared because of some subtle change in how the settings are initialised. This is resulting in the settings file being written during start-up of the Thing, using cached values for (most?) properties.
I think we can probably restructure the settings to get rid of the problem. However, I think it might be preferred to fix it in LabThings if we can. Restructuring the OFM code to be easier to understand would still, I think, be useful - but might be a longer-term change.
A log from before the bug, with a bunch of extra stuff added to the camera class.
Filtered log:
Full log
``` [2026-07-02 10:56:30,303] [INFO] OFM server root logger has been set up at INFO level [2026-07-02 10:56:30,336] [INFO] Starting picamera __init__ [2026-07-02 10:56:30,341] [INFO] stopping __init__ [2026-07-02 10:56:30,372] [INFO] Setting exposure time to 1984, previous was 500. [2026-07-02 10:56:30,373] [INFO] Current streaming status: False [2026-07-02 10:56:31,609] [INFO] Started server process [79330] [2026-07-02 10:56:31,610] [INFO] Waiting for application startup. [2026-07-02 10:56:31,623] [INFO] starting StreamingPiCamera2.__enter__ [2026-07-02 10:56:31,624] [INFO] starting _initialise_picamera [2026-07-02 10:56:31,628] [INFO] Creating new Picamera2 object [2026-07-02 10:56:31,680] [INFO] Initialization successful. [2026-07-02 10:56:31,680] [INFO] Camera now open. [2026-07-02 10:56:31,683] [INFO] stopping _initialise_picamera [2026-07-02 10:56:31,685] [INFO] Getting exposure time. Cached value 1984. [2026-07-02 10:56:31,685] [INFO] Returning 1984 [2026-07-02 10:56:31,688] [INFO] Camera configuration has been adjusted! [2026-07-02 10:56:31,690] [INFO] Configuration successful! [2026-07-02 10:56:31,727] [INFO] Starting picamera MJPEG stream... [2026-07-02 10:56:31,761] [INFO] Camera started [2026-07-02 10:56:31,796] [INFO] stopping StreamingPiCamera2.__enter__ [2026-07-02 10:56:31,797] [INFO] Initialising ExtensibleSerialInstrument on port None [2026-07-02 10:56:31,798] [INFO] Updating ESI port settings [2026-07-02 10:56:31,798] [INFO] Opening ESI connection to port None [2026-07-02 10:56:31,806] [INFO] Creating serial.Serial instance... [2026-07-02 10:56:31,808] [INFO] Created Serial(port='/dev/ttyAMA0', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False) [2026-07-02 10:56:31,808] [INFO] Testing communication to SangaBoard [2026-07-02 10:56:31,808] [INFO] Running firmware checks... [2026-07-02 10:56:31,814] [INFO] Firmware response: Sangaboard Firmware v1.0.4 [2026-07-02 10:56:31,816] [INFO] Success! [2026-07-02 10:56:31,817] [INFO] Creating serial.Serial instance... [2026-07-02 10:56:31,818] [INFO] Created Serial(port='/dev/ttyAMA0', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False) [2026-07-02 10:56:31,818] [INFO] Testing communication to SangaBoard [2026-07-02 10:56:31,819] [INFO] Running firmware checks... [2026-07-02 10:56:31,824] [INFO] Firmware response: Sangaboard Firmware v1.0.4 [2026-07-02 10:56:31,825] [INFO] Opened ESI connection to port None [2026-07-02 10:56:31,826] [INFO] Checking valid firmware... [2026-07-02 10:56:31,826] [INFO] Running firmware checks... [2026-07-02 10:56:31,831] [INFO] Firmware response: Sangaboard Firmware v1.0.4 [2026-07-02 10:56:31,832] [INFO] Loading modules... [2026-07-02 10:56:31,848] [INFO] Enabling backwards-compatible behaviour on new Sangaboard firmware [2026-07-02 10:56:31,872] [INFO] Application startup complete. [2026-07-02 10:56:31,877] [INFO] Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit) ```Log showing the problem
Filtered log:
Full log