{
    "/camera/": {
        "title": "SimulatedCamera",
        "properties": {
            "background_detector_data": {
                "description": "The data for each background detector, used to save to disk.",
                "title": "The data for each background detector, used to save to disk.",
                "type": "object",
                "forms": [
                    {
                        "href": "/camera/background_detector_data",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "background_detector_status": {
                "description": "The status of the active detector for the UI.",
                "title": "The status of the active detector for the UI.",
                "type": "object",
                "properties": {
                    "ready": {
                        "title": "Ready",
                        "type": "boolean"
                    },
                    "settings": {
                        "title": "Settings",
                        "type": "object"
                    },
                    "settings_schema": {
                        "title": "Settings Schema",
                        "type": "object"
                    }
                },
                "required": [
                    "ready",
                    "settings",
                    "settings_schema"
                ],
                "forms": [
                    {
                        "href": "/camera/background_detector_status",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "detector_name": {
                "description": "The name of the active background selector.",
                "title": "The name of the active background selector.",
                "type": "string",
                "forms": [
                    {
                        "href": "/camera/detector_name",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "downsampled_array_factor": {
                "title": "downsampled_array_factor",
                "type": "integer",
                "forms": [
                    {
                        "href": "/camera/downsampled_array_factor",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "manual_camera_settings": {
                "description": "The camera settings to expose as property controls in the settings panel.",
                "title": "The camera settings to expose as property controls in the settings panel.",
                "type": "array",
                "items": {
                    "description": "The data required for creating an actionButton in Vue.\n\nCurrently this cannot be used to submitData, or to submitOnEvent.",
                    "title": "PropertyControl",
                    "type": "object",
                    "properties": {
                        "thing": {
                            "title": "Thing",
                            "type": "string"
                        },
                        "property_name": {
                            "title": "Property Name",
                            "type": "string"
                        },
                        "label": {
                            "title": "Label",
                            "type": "string"
                        },
                        "read_back": {
                            "title": "Read Back",
                            "default": false,
                            "type": "boolean"
                        },
                        "read_back_delay": {
                            "title": "Read Back Delay",
                            "default": 1000,
                            "type": "integer"
                        }
                    },
                    "required": [
                        "thing",
                        "property_name",
                        "label"
                    ]
                },
                "forms": [
                    {
                        "href": "/camera/manual_camera_settings",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "noise_level": {
                "title": "noise_level",
                "type": "number",
                "forms": [
                    {
                        "href": "/camera/noise_level",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "primary_calibration_actions": {
                "description": "The calibration actions for both calibration wizard and settings panel.",
                "title": "The calibration actions for both calibration wizard and settings panel.",
                "type": "array",
                "items": {
                    "description": "The data required for creating an actionButton in Vue.\n\nCurrently this cannot be used to submitData, or to submitOnEvent.",
                    "title": "ActionButton",
                    "type": "object",
                    "properties": {
                        "thing": {
                            "title": "Thing",
                            "type": "string"
                        },
                        "action": {
                            "title": "Action",
                            "type": "string"
                        },
                        "poll_interval": {
                            "title": "Poll Interval",
                            "default": 1,
                            "type": "integer"
                        },
                        "submit_label": {
                            "title": "Submit Label",
                            "default": "Submit",
                            "type": "string"
                        },
                        "can_terminate": {
                            "title": "Can Terminate",
                            "default": true,
                            "type": "boolean"
                        },
                        "requires_confirmation": {
                            "title": "Requires Confirmation",
                            "default": false,
                            "type": "boolean"
                        },
                        "confirmation_message": {
                            "title": "Confirmation Message",
                            "default": "Start task?",
                            "type": "string"
                        },
                        "button_primary": {
                            "title": "Button Primary",
                            "default": true,
                            "type": "boolean"
                        },
                        "modal_progress": {
                            "title": "Modal Progress",
                            "default": false,
                            "type": "boolean"
                        },
                        "notify_on_success": {
                            "title": "Notify On Success",
                            "default": false,
                            "type": "boolean"
                        },
                        "success_message": {
                            "title": "Success Message",
                            "default": "Success!",
                            "type": "string"
                        }
                    },
                    "required": [
                        "thing",
                        "action"
                    ]
                },
                "forms": [
                    {
                        "href": "/camera/primary_calibration_actions",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "secondary_calibration_actions": {
                "description": "The calibration actions that appear only in settings panel.",
                "title": "The calibration actions that appear only in settings panel.",
                "type": "array",
                "items": {
                    "description": "The data required for creating an actionButton in Vue.\n\nCurrently this cannot be used to submitData, or to submitOnEvent.",
                    "title": "ActionButton",
                    "type": "object",
                    "properties": {
                        "thing": {
                            "title": "Thing",
                            "type": "string"
                        },
                        "action": {
                            "title": "Action",
                            "type": "string"
                        },
                        "poll_interval": {
                            "title": "Poll Interval",
                            "default": 1,
                            "type": "integer"
                        },
                        "submit_label": {
                            "title": "Submit Label",
                            "default": "Submit",
                            "type": "string"
                        },
                        "can_terminate": {
                            "title": "Can Terminate",
                            "default": true,
                            "type": "boolean"
                        },
                        "requires_confirmation": {
                            "title": "Requires Confirmation",
                            "default": false,
                            "type": "boolean"
                        },
                        "confirmation_message": {
                            "title": "Confirmation Message",
                            "default": "Start task?",
                            "type": "string"
                        },
                        "button_primary": {
                            "title": "Button Primary",
                            "default": true,
                            "type": "boolean"
                        },
                        "modal_progress": {
                            "title": "Modal Progress",
                            "default": false,
                            "type": "boolean"
                        },
                        "notify_on_success": {
                            "title": "Notify On Success",
                            "default": false,
                            "type": "boolean"
                        },
                        "success_message": {
                            "title": "Success Message",
                            "default": "Success!",
                            "type": "string"
                        }
                    },
                    "required": [
                        "thing",
                        "action"
                    ]
                },
                "forms": [
                    {
                        "href": "/camera/secondary_calibration_actions",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "settling_time": {
                "title": "settling_time",
                "type": "number",
                "forms": [
                    {
                        "href": "/camera/settling_time",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "stream_active": {
                "description": "Whether the MJPEG stream is active.",
                "title": "Whether the MJPEG stream is active.",
                "type": "boolean",
                "forms": [
                    {
                        "href": "/camera/stream_active",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            }
        },
        "actions": {
            "capture_and_save": {
                "description": ":param jpeg_path: The path to save the file to\n:param logger: This should be injected automatically by Labthings FastAPI\n    when calling the action\n:param metadata_getter: This should be injected automatically by Labthings\n    FastAPI when calling the action\n:param save_resolution: can be set to resize the image before saving. By\n    default this is None meaning that the image is saved at original resolution.",
                "title": "Capture an image and save it to disk.",
                "forms": [
                    {
                        "href": "/camera/capture_and_save",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "capture_and_save_input",
                    "type": "object",
                    "properties": {
                        "jpeg_path": {
                            "title": "Jpeg Path",
                            "type": "string"
                        },
                        "save_resolution": {
                            "title": "Save Resolution",
                            "oneOf": [
                                {
                                    "type": "array",
                                    "items": [
                                        {
                                            "type": "integer"
                                        },
                                        {
                                            "type": "integer"
                                        }
                                    ],
                                    "maxItems": 2,
                                    "minItems": 2
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    },
                    "required": [
                        "jpeg_path"
                    ]
                },
                "output": {
                    "title": "capture_and_save_output",
                    "type": "null"
                }
            },
            "capture_array": {
                "description": "This function will produce a nested list containing an uncompressed RGB image.\nIt's likely to be highly inefficient - raw and/or uncompressed captures using\nbinary image formats will be added in due course.",
                "title": "Acquire one image from the camera and return as an array.",
                "forms": [
                    {
                        "href": "/camera/capture_array",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "capture_array_input",
                    "type": "object",
                    "properties": {
                        "resolution": {
                            "title": "Resolution",
                            "enum": [
                                "main",
                                "full"
                            ],
                            "default": "full",
                            "type": "string"
                        }
                    }
                },
                "output": {
                    "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                    "title": "capture_array_output",
                    "oneOf": [
                        {
                            "type": "integer"
                        },
                        {
                            "type": "number"
                        },
                        {
                            "type": "array",
                            "items": {
                                "oneOf": [
                                    {
                                        "type": "integer"
                                    },
                                    {
                                        "type": "number"
                                    }
                                ]
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "oneOf": [
                                        {
                                            "type": "integer"
                                        },
                                        {
                                            "type": "number"
                                        }
                                    ]
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {}
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            },
            "capture_downsampled_array": {
                "description": "* The array is downsamples by the thing property `downsampled_array_factor`.\n* The default capture array arguments are used.\n\nThis method provides the interface expected by the camera_stage_mapping.",
                "title": "Acquire one image from the camera, downsample, and return as an array.",
                "forms": [
                    {
                        "href": "/camera/capture_downsampled_array",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "capture_downsampled_array_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                    "title": "capture_downsampled_array_output",
                    "oneOf": [
                        {
                            "type": "integer"
                        },
                        {
                            "type": "number"
                        },
                        {
                            "type": "array",
                            "items": {
                                "oneOf": [
                                    {
                                        "type": "integer"
                                    },
                                    {
                                        "type": "number"
                                    }
                                ]
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "oneOf": [
                                        {
                                            "type": "integer"
                                        },
                                        {
                                            "type": "number"
                                        }
                                    ]
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "array",
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {}
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            },
            "capture_jpeg": {
                "description": "This function will produce a JPEG image.\n        ",
                "title": "Acquire one image from the camera and return as a JPEG blob.",
                "forms": [
                    {
                        "href": "/camera/capture_jpeg",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "capture_jpeg_input",
                    "type": "object",
                    "properties": {
                        "resolution": {
                            "title": "Resolution",
                            "enum": [
                                "main",
                                "full"
                            ],
                            "default": "main",
                            "type": "string"
                        }
                    }
                },
                "output": {
                    "description": "A class representing a JPEG image as a LabThings FastAPI Blob.",
                    "title": "capture_jpeg_output",
                    "type": "object",
                    "properties": {
                        "href": {
                            "title": "Href",
                            "type": "string"
                        },
                        "media_type": {
                            "title": "Media Type",
                            "default": "image/jpeg",
                            "type": "string"
                        },
                        "rel": {
                            "title": "Rel",
                            "const": "output",
                            "default": "output",
                            "type": "string"
                        },
                        "description": {
                            "title": "Description",
                            "default": "The output from this action is not serialised to JSON, so it must be retrieved as a file. This link will return the file.",
                            "type": "string"
                        }
                    },
                    "required": [
                        "href"
                    ]
                }
            },
            "capture_to_memory": {
                "description": "Note that only one image is held in memory so this will overwrite any image\nin memory.\n\n:param logger: This should be injected automatically by Labthings FastAPI\n    when calling the action\n:param metadata_getter: This should be injected automatically by Labthings\n    FastAPI when calling the action\n:param buffer_max: The maximum number of images that should be in the buffer\n    once this images is added. Default is 1.\n\n:returns: the buffer id of the image captured",
                "title": "Capture an image to memory. This can be saved later with ``save_from_memory``.",
                "forms": [
                    {
                        "href": "/camera/capture_to_memory",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "capture_to_memory_input",
                    "type": "object",
                    "properties": {
                        "buffer_max": {
                            "title": "Buffer Max",
                            "default": 1,
                            "type": "integer"
                        }
                    }
                },
                "output": {
                    "title": "capture_to_memory_output",
                    "type": "integer"
                }
            },
            "clear_buffers": {
                "description": "Clear all images in memory.",
                "title": "Clear all images in memory.",
                "forms": [
                    {
                        "href": "/camera/clear_buffers",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "clear_buffers_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "clear_buffers_output",
                    "type": "null"
                }
            },
            "discard_frames": {
                "description": "There is nothing to do as this is a simulation!\n        ",
                "title": "Discard frames so that the next frame captured is fresh.",
                "forms": [
                    {
                        "href": "/camera/discard_frames",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "discard_frames_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "discard_frames_output",
                    "type": "null"
                }
            },
            "grab_jpeg": {
                "description": "This differs from ``capture_jpeg`` in that it does not pause the MJPEG\npreview stream. Instead, we simply return the next frame from that\nstream (either \"main\" for the preview stream, or \"lores\" for the low\nresolution preview). No metadata is returned.",
                "title": "Acquire one image from the preview stream and return as an array.",
                "forms": [
                    {
                        "href": "/camera/grab_jpeg",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "grab_jpeg_input",
                    "type": "object",
                    "properties": {
                        "stream_name": {
                            "title": "Stream Name",
                            "enum": [
                                "main",
                                "lores"
                            ],
                            "default": "main",
                            "type": "string"
                        }
                    }
                },
                "output": {
                    "description": "A class representing a JPEG image as a LabThings FastAPI Blob.",
                    "title": "grab_jpeg_output",
                    "type": "object",
                    "properties": {
                        "href": {
                            "title": "Href",
                            "type": "string"
                        },
                        "media_type": {
                            "title": "Media Type",
                            "default": "image/jpeg",
                            "type": "string"
                        },
                        "rel": {
                            "title": "Rel",
                            "const": "output",
                            "default": "output",
                            "type": "string"
                        },
                        "description": {
                            "title": "Description",
                            "default": "The output from this action is not serialised to JSON, so it must be retrieved as a file. This link will return the file.",
                            "type": "string"
                        }
                    },
                    "required": [
                        "href"
                    ]
                }
            },
            "grab_jpeg_size": {
                "description": "Acquire one image from the preview stream and return its size.",
                "title": "Acquire one image from the preview stream and return its size.",
                "forms": [
                    {
                        "href": "/camera/grab_jpeg_size",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "grab_jpeg_size_input",
                    "type": "object",
                    "properties": {
                        "stream_name": {
                            "title": "Stream Name",
                            "enum": [
                                "main",
                                "lores"
                            ],
                            "default": "main",
                            "type": "string"
                        }
                    }
                },
                "output": {
                    "title": "grab_jpeg_size_output",
                    "type": "integer"
                }
            },
            "image_is_sample": {
                "description": "Label the current image as either background or sample.",
                "title": "Label the current image as either background or sample.",
                "forms": [
                    {
                        "href": "/camera/image_is_sample",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "image_is_sample_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "image_is_sample_output",
                    "type": "array",
                    "items": [
                        {
                            "type": "boolean"
                        },
                        {
                            "type": "string"
                        }
                    ],
                    "maxItems": 2,
                    "minItems": 2
                }
            },
            "load_sample": {
                "description": "Show the simulated sample.",
                "title": "Show the simulated sample.",
                "forms": [
                    {
                        "href": "/camera/load_sample",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "load_sample_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "load_sample_output"
                }
            },
            "remove_sample": {
                "description": "Show the simulated background with no sample.",
                "title": "Show the simulated background with no sample.",
                "forms": [
                    {
                        "href": "/camera/remove_sample",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "remove_sample_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "remove_sample_output"
                }
            },
            "save_from_memory": {
                "description": ":param jpeg_path: The path to save the file to\n:param logger: This should be injected automatically by Labthings FastAPI\n    when calling the action\n:param save_resolution: can be set to resize the image before saving. By\n    default this is None meaning that the image is saved at original\n    resolution.\n:param buffer_id: The buffer id of the image to save, this was returned by\n    ``capture_to_memory``",
                "title": "Save an image that has been captured to memory.",
                "forms": [
                    {
                        "href": "/camera/save_from_memory",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "save_from_memory_input",
                    "type": "object",
                    "properties": {
                        "jpeg_path": {
                            "title": "Jpeg Path",
                            "type": "string"
                        },
                        "save_resolution": {
                            "title": "Save Resolution",
                            "oneOf": [
                                {
                                    "type": "array",
                                    "items": [
                                        {
                                            "type": "integer"
                                        },
                                        {
                                            "type": "integer"
                                        }
                                    ],
                                    "maxItems": 2,
                                    "minItems": 2
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        },
                        "buffer_id": {
                            "title": "Buffer Id",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    },
                    "required": [
                        "jpeg_path"
                    ]
                },
                "output": {
                    "title": "save_from_memory_output",
                    "type": "null"
                }
            },
            "set_background": {
                "description": "This should be run when the microscope is looking at an empty region,\nand will calculate the mean and standard deviation of the pixel values\nin the LUV colourspace. These values will then be used to compare\nfuture images to the distribution, to determine if each pixel is\nforeground or background.",
                "title": "Grab an image, and use its statistics to set the background.",
                "forms": [
                    {
                        "href": "/camera/set_background",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "set_background_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "set_background_output",
                    "type": "null"
                }
            },
            "settle": {
                "description": "This function will sleep for the given time, and clear the buffer after sleeping.\nAs such, the next frame captured from the camera after running this function will\nalways be captured after settling.\n\nThis method provides the interface expected by the camera_stage_mapping.",
                "title": "Sleep for the settling time, ready to provide a fresh frame.",
                "forms": [
                    {
                        "href": "/camera/settle",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "settle_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "settle_output",
                    "type": "null"
                }
            },
            "start_streaming": {
                "description": "The start_streaming method is used a camera ``Thing`` to begin streaming\nimages or to adjust the stream resolution if streaming is already active.\n\nThe simulation camera does not currently support the resolution argument.\nIt will always issue a warning that the resolution is not respected.\nIf called while already streaming, the warning will be emitted and no other\naction will be taken.",
                "title": "Start the live stream.",
                "forms": [
                    {
                        "href": "/camera/start_streaming",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "start_streaming_input",
                    "type": "object",
                    "properties": {
                        "main_resolution": {
                            "title": "Main Resolution",
                            "default": [
                                820,
                                616
                            ],
                            "type": "array",
                            "items": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "integer"
                                }
                            ],
                            "maxItems": 2,
                            "minItems": 2
                        },
                        "buffer_count": {
                            "title": "Buffer Count",
                            "default": 1,
                            "type": "integer"
                        }
                    }
                },
                "output": {
                    "title": "start_streaming_output",
                    "type": "null"
                }
            },
            "update_detector_settings": {
                "description": "This is an action not a setting/property as the data model depends on the\nselected detector. As such, it cannot be specified with the necessary precision\nto be included in a ThingDescription as a setting/property, while retaining\nenough useful information to communicate to the UI how it is set and read.\n\nThe information on how to read the settings is exposed in\n``background_detector_status``.",
                "title": "Update the settings of the current detector.",
                "forms": [
                    {
                        "href": "/camera/update_detector_settings",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "update_detector_settings_input",
                    "type": "object",
                    "properties": {
                        "data": {
                            "title": "Data"
                        }
                    },
                    "required": [
                        "data"
                    ]
                },
                "output": {
                    "title": "update_detector_settings_output",
                    "type": "null"
                }
            }
        },
        "base": "http://testserver/",
        "securityDefinitions": {
            "no_security": {
                "description": "No security",
                "scheme": "nosec"
            }
        },
        "security": "no_security",
        "@context": "https://www.w3.org/2022/wot/td/v1.1"
    },
    "/stage/": {
        "title": "DummyStage",
        "properties": {
            "axis_inverted": {
                "title": "axis_inverted",
                "type": "object",
                "forms": [
                    {
                        "href": "/stage/axis_inverted",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "axis_names": {
                "description": "The names of the stage's axes, in order.",
                "title": "The names of the stage's axes, in order.",
                "type": "array",
                "items": {
                    "type": "string"
                },
                "forms": [
                    {
                        "href": "/stage/axis_names",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "moving": {
                "title": "moving",
                "type": "boolean",
                "forms": [
                    {
                        "href": "/stage/moving",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "position": {
                "description": "Current position of the stage.",
                "title": "Current position of the stage.",
                "type": "object",
                "forms": [
                    {
                        "href": "/stage/position",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            }
        },
        "actions": {
            "get_xyz_position": {
                "description": ":raises KeyError: if this stage does not have axes named \"x\", \"y\", and \"z\".\n\nThis method provides the interface expected by the camera_stage_mapping.",
                "title": "Return a tuple containing (x, y, z) position.",
                "forms": [
                    {
                        "href": "/stage/get_xyz_position",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "get_xyz_position_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "get_xyz_position_output",
                    "type": "array",
                    "items": [
                        {
                            "type": "integer"
                        },
                        {
                            "type": "integer"
                        },
                        {
                            "type": "integer"
                        }
                    ],
                    "maxItems": 3,
                    "minItems": 3
                }
            },
            "invert_axis_direction": {
                "description": ":param axis: The axis name (x, y or z) to invert.\n        ",
                "title": "Invert the direction setting of the given axis.",
                "forms": [
                    {
                        "href": "/stage/invert_axis_direction",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "invert_axis_direction_input",
                    "type": "object",
                    "properties": {
                        "axis": {
                            "title": "Axis",
                            "enum": [
                                "x",
                                "y",
                                "z"
                            ],
                            "type": "string"
                        }
                    },
                    "required": [
                        "axis"
                    ]
                },
                "output": {
                    "title": "invert_axis_direction_output"
                }
            },
            "move_absolute": {
                "description": "Make an absolute move. Keyword arguments should be axis names.",
                "title": "Make an absolute move. Keyword arguments should be axis names.",
                "forms": [
                    {
                        "href": "/stage/move_absolute",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "move_absolute_input",
                    "type": "object",
                    "properties": {
                        "block_cancellation": {
                            "title": "Block Cancellation",
                            "default": false,
                            "type": "boolean"
                        }
                    }
                },
                "output": {
                    "title": "move_absolute_output"
                }
            },
            "move_relative": {
                "description": "Make a relative move. Keyword arguments should be axis names.",
                "title": "Make a relative move. Keyword arguments should be axis names.",
                "forms": [
                    {
                        "href": "/stage/move_relative",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "move_relative_input",
                    "type": "object",
                    "properties": {
                        "block_cancellation": {
                            "title": "Block Cancellation",
                            "default": false,
                            "type": "boolean"
                        }
                    }
                },
                "output": {
                    "title": "move_relative_output"
                }
            },
            "move_to_xyz_position": {
                "description": ":param cancel: A cancel hook for cancelling the move. This dependency should be\n    injected automatically by LabThings-FastAPI\n:param xyz_pos: The (x, y, z) position to move to.\n\n:raises KeyError: if this stage does not have axes named \"x\", \"y\", and \"z\".\n\nThis method provides the interface expected by the camera_stage_mapping.",
                "title": "Move to the location specified by an (x, y, z) tuple.",
                "forms": [
                    {
                        "href": "/stage/move_to_xyz_position",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "move_to_xyz_position_input",
                    "type": "object",
                    "properties": {
                        "xyz_pos": {
                            "title": "Xyz Pos",
                            "type": "array",
                            "items": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "integer"
                                }
                            ],
                            "maxItems": 3,
                            "minItems": 3
                        }
                    },
                    "required": [
                        "xyz_pos"
                    ]
                },
                "output": {
                    "title": "move_to_xyz_position_output",
                    "type": "null"
                }
            },
            "set_zero_position": {
                "description": "This action does not move the stage, but resets the position to zero.\nIt is intended for use after manually or automatically recentring the\nstage.",
                "title": "Make the current position zero in all axes.",
                "forms": [
                    {
                        "href": "/stage/set_zero_position",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "set_zero_position_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "title": "set_zero_position_output"
                }
            }
        },
        "base": "http://testserver/",
        "securityDefinitions": {
            "no_security": {
                "description": "No security",
                "scheme": "nosec"
            }
        },
        "security": "no_security",
        "@context": "https://www.w3.org/2022/wot/td/v1.1"
    },
    "/autofocus/": {
        "title": "AutofocusThing",
        "properties": {
            "stack_dz": {
                "title": "stack_dz",
                "type": "integer",
                "forms": [
                    {
                        "href": "/autofocus/stack_dz",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "stack_images_to_save": {
                "title": "stack_images_to_save",
                "type": "integer",
                "forms": [
                    {
                        "href": "/autofocus/stack_images_to_save",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            },
            "stack_min_images_to_test": {
                "title": "stack_min_images_to_test",
                "type": "integer",
                "forms": [
                    {
                        "href": "/autofocus/stack_min_images_to_test",
                        "op": [
                            "readproperty",
                            "writeproperty"
                        ]
                    }
                ]
            }
        },
        "actions": {
            "fast_autofocus": {
                "description": "This method will will move down by dz/2, sweep up by dz, and then evaluate\nthe position where the image was sharpest. We'll then move back down, and\nfinally up to the sharpest point.",
                "title": "Sweep the stage up and down, then move to the sharpest point.",
                "forms": [
                    {
                        "href": "/autofocus/fast_autofocus",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "fast_autofocus_input",
                    "type": "object",
                    "properties": {
                        "dz": {
                            "title": "Dz",
                            "default": 2000,
                            "type": "integer"
                        },
                        "start": {
                            "title": "Start",
                            "default": "centre",
                            "type": "string"
                        }
                    }
                },
                "output": {
                    "description": "A BaseModel with the position and sharpness data from JPEGSharpnessMonitor.\n\nEach JPEG Size (representing a sharpness metric) has an associated timestamp,\nas does each stage position. The stage positions need to be interpolated so\nthey correspond with the image timestamps.",
                    "title": "fast_autofocus_output",
                    "type": "object",
                    "properties": {
                        "jpeg_times": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "jpeg_sizes": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "stage_times": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "stage_positions": {
                            "title": "Stage Positions",
                            "type": "array",
                            "items": {
                                "type": "object"
                            }
                        }
                    },
                    "required": [
                        "jpeg_times",
                        "jpeg_sizes",
                        "stage_times",
                        "stage_positions"
                    ]
                }
            },
            "looping_autofocus": {
                "description": "This action will run the ``fast_autofocus`` action until it settles on a point\nin the middle 3/5 of its range. Such logic can be helpful if the microscope\nis close to focus, but not quite within ``dz/2``. It will attempt to autofocus\nup to 10 times.",
                "title": "Repeatedly autofocus the stage until it looks focused.",
                "forms": [
                    {
                        "href": "/autofocus/looping_autofocus",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "looping_autofocus_input",
                    "type": "object",
                    "properties": {
                        "dz": {
                            "title": "Dz",
                            "default": 2000
                        },
                        "start": {
                            "title": "Start",
                            "default": "centre"
                        }
                    }
                },
                "output": {
                    "title": "looping_autofocus_output"
                }
            },
            "run_smart_stack": {
                "description": "A smart stack captures images offset in z, testing whether the sharpest image\nis towards the centre of the stack.\n\nThe sharpest image, and optionally images around the sharpest, will be saved\nto the images_dir with their coordinates in the filename.\n\n\n:param cam: Camera Dependency supplied by LabThings dependency injection\n:param stage: Stage Dependency supplied by LabThings dependency injection\n:param sharpness_monitor: Sharpness Monitor Dependency (for focus detection)\n    supplied by LabThings dependency injection\n:param images_dir: the folder to save all images\n:param autofocus_dz: the range to autofocus over if a stack fails\n:param save_resolution: The resolution the images should be saved at, the\n    images will be resampled if this doesn't match the camera's capture\n    resolution\n\n:returns: A tuple containing:\n\n    * A boolean, True if stack was successfully\n    * The z position of the sharpest image",
                "title": "Run a smart stack.",
                "forms": [
                    {
                        "href": "/autofocus/run_smart_stack",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "run_smart_stack_input",
                    "type": "object",
                    "properties": {
                        "images_dir": {
                            "title": "Images Dir",
                            "type": "string"
                        },
                        "autofocus_dz": {
                            "title": "Autofocus Dz",
                            "type": "integer"
                        },
                        "save_resolution": {
                            "title": "Save Resolution",
                            "type": "array",
                            "items": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "integer"
                                }
                            ],
                            "maxItems": 2,
                            "minItems": 2
                        }
                    },
                    "required": [
                        "images_dir",
                        "autofocus_dz",
                        "save_resolution"
                    ]
                },
                "output": {
                    "title": "run_smart_stack_output",
                    "type": "array",
                    "items": [
                        {
                            "type": "boolean"
                        },
                        {
                            "type": "integer"
                        }
                    ],
                    "maxItems": 2,
                    "minItems": 2
                }
            },
            "z_move_and_measure_sharpness": {
                "description": "This method will will make a series of relative moves in z, and\nreturn the sharpness (JPEG size) vs time, along with timestamps\nfor the moves. This can be used to calibrate autofocus.\n\nEach move is relative to the last one, i.e. we will finish at\n``sum(dz)`` relative to the starting position.\n\nIf ``wait`` is specified, we will wait for that many seconds\nbetween moves.",
                "title": "Make a move (or a series of moves) and monitor sharpness.",
                "forms": [
                    {
                        "href": "/autofocus/z_move_and_measure_sharpness",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "z_move_and_measure_sharpness_input",
                    "type": "object",
                    "properties": {
                        "dz": {
                            "title": "Dz",
                            "type": "array",
                            "items": {
                                "type": "integer"
                            }
                        },
                        "wait": {
                            "title": "Wait",
                            "default": 0,
                            "type": "number"
                        }
                    },
                    "required": [
                        "dz"
                    ]
                },
                "output": {
                    "description": "A BaseModel with the position and sharpness data from JPEGSharpnessMonitor.\n\nEach JPEG Size (representing a sharpness metric) has an associated timestamp,\nas does each stage position. The stage positions need to be interpolated so\nthey correspond with the image timestamps.",
                    "title": "z_move_and_measure_sharpness_output",
                    "type": "object",
                    "properties": {
                        "jpeg_times": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "jpeg_sizes": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "stage_times": {
                            "description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.",
                            "title": "NestedListOfNumbersModel",
                            "oneOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "number"
                                            }
                                        ]
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "integer"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "oneOf": [
                                                    {
                                                        "type": "integer"
                                                    },
                                                    {
                                                        "type": "number"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "oneOf": [
                                                        {
                                                            "type": "integer"
                                                        },
                                                        {
                                                            "type": "number"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "oneOf": [
                                                            {
                                                                "type": "integer"
                                                            },
                                                            {
                                                                "type": "number"
                                                            }
                                                        ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "oneOf": [
                                                                {
                                                                    "type": "integer"
                                                                },
                                                                {
                                                                    "type": "number"
                                                                }
                                                            ]
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "array",
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "array",
                                                            "items": {}
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "stage_positions": {
                            "title": "Stage Positions",
                            "type": "array",
                            "items": {
                                "type": "object"
                            }
                        }
                    },
                    "required": [
                        "jpeg_times",
                        "jpeg_sizes",
                        "stage_times",
                        "stage_positions"
                    ]
                }
            }
        },
        "base": "http://testserver/",
        "securityDefinitions": {
            "no_security": {
                "description": "No security",
                "scheme": "nosec"
            }
        },
        "security": "no_security",
        "@context": "https://www.w3.org/2022/wot/td/v1.1"
    },
    "/camera_stage_mapping/": {
        "title": "CameraStageMapper",
        "properties": {
            "image_resolution": {
                "description": "The image size used to calibrate the image_to_stage_displacement_matrix.",
                "title": "The image size used to calibrate the image_to_stage_displacement_matrix.",
                "oneOf": [
                    {
                        "type": "array",
                        "items": [
                            {
                                "type": "number"
                            },
                            {
                                "type": "number"
                            }
                        ],
                        "maxItems": 2,
                        "minItems": 2
                    },
                    {
                        "type": "null"
                    }
                ],
                "forms": [
                    {
                        "href": "/camera_stage_mapping/image_resolution",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "image_to_stage_displacement_matrix": {
                "description": "Note that this matrix is defined using \"matrix coordinates\", i.e. image coordinates\nmay be (y,x). This is an artifact of the way numpy, opencv, etc. define images. If\nyou are making use of this matrix in your own code, you will need to take care of\nthat conversion.\n\nIt is often helpful to give a concrete example: to make a move in image coordinates\n(``dy``, ``dx``), where ``dx`` is horizontal, i.e. the longer dimension of the image, you\nshould move the stage by:\n\n.. code-block:: python\n\n    stage_disp = np.dot(\n        np.array(image_to_stage_displacement_matrix),\n        np.array([dy,dx]),\n    )",
                "title": "A 2x2 matrix that converts displacement in image coordinates to stage coordinates.",
                "oneOf": [
                    {
                        "type": "array",
                        "items": {
                            "type": "array",
                            "items": {
                                "type": "number"
                            }
                        }
                    },
                    {
                        "type": "null"
                    }
                ],
                "forms": [
                    {
                        "href": "/camera_stage_mapping/image_to_stage_displacement_matrix",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "last_calibration": {
                "title": "last_calibration",
                "oneOf": [
                    {
                        "type": "object"
                    },
                    {
                        "type": "null"
                    }
                ],
                "forms": [
                    {
                        "href": "/camera_stage_mapping/last_calibration",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            },
            "thing_state": {
                "description": "Summary metadata describing the current state of the Thing.",
                "title": "Summary metadata describing the current state of the Thing.",
                "type": "object",
                "forms": [
                    {
                        "href": "/camera_stage_mapping/thing_state",
                        "op": [
                            "readproperty"
                        ]
                    }
                ]
            }
        },
        "actions": {
            "calibrate_1d": {
                "description": "Move a microscope's stage in 1D, and figure out the relationship with the camera.",
                "title": "Move a microscope's stage in 1D, and figure out the relationship with the camera.",
                "forms": [
                    {
                        "href": "/camera_stage_mapping/calibrate_1d",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "calibrate_1d_input",
                    "type": "object",
                    "properties": {
                        "direction": {
                            "title": "Direction",
                            "type": "array",
                            "items": [
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "number"
                                },
                                {
                                    "type": "number"
                                }
                            ],
                            "maxItems": 3,
                            "minItems": 3
                        }
                    },
                    "required": [
                        "direction"
                    ]
                },
                "output": {
                    "description": "A `pydantic` model for a dictionary that converts arrays to lists.",
                    "title": "calibrate_1d_output",
                    "type": "object"
                }
            },
            "calibrate_xy": {
                "description": "This performs two 1d calibrations in x and y, then combines their results.\n        ",
                "title": "Move the microscope's stage in X and Y, to calibrate its relationship to the camera.",
                "forms": [
                    {
                        "href": "/camera_stage_mapping/calibrate_xy",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "description": "Represent the input of an action that never takes parameters.\n\nThis may be either an empty dictionary or ``None``.",
                    "title": "calibrate_xy_input",
                    "oneOf": [
                        {
                            "description": "A model representing an object that must have no keys.",
                            "title": "StrictEmptyObject",
                            "type": "object",
                            "properties": {}
                        },
                        {
                            "type": "null"
                        }
                    ]
                },
                "output": {
                    "description": "A `pydantic` model for a dictionary that converts arrays to lists.",
                    "title": "calibrate_xy_output",
                    "type": "object"
                }
            },
            "move_in_image_coordinates": {
                "description": "NB x and y here refer to what is usually understood to be the horizontal and\nvertical axes of the image. In many toolkits, \"matrix indices\" are used, which\nswap the order of these coordinates. This includes opencv and PIL. So, don't be\nsurprised if you find it necessary to swap x and y around.\n\nAs a general rule, ``x`` usually corresponds to the longer dimension of the image,\nand ``y`` to the shorter one. Checking what shape your chosen toolkit reports for\nan image usually helps resolve any ambiguity.",
                "title": "Move by a given number of pixels on the camera.",
                "forms": [
                    {
                        "href": "/camera_stage_mapping/move_in_image_coordinates",
                        "op": [
                            "invokeaction"
                        ]
                    }
                ],
                "input": {
                    "title": "move_in_image_coordinates_input",
                    "type": "object",
                    "properties": {
                        "x": {
                            "title": "X",
                            "type": "number"
                        },
                        "y": {
                            "title": "Y",
                            "type": "number"
                        }
                    },
                    "required": [
                        "x",
                        "y"
                    ]
                },
                "output": {
                    "title": "move_in_image_coordinates_output"
                }
            }
        },
        "base": "http://testserver/",
        "securityDefinitions": {
            "no_security": {
                "description": "No security",
                "scheme": "nosec"
            }
        },
        "security": "no_security",
        "@context": "https://www.w3.org/2022/wot/td/v1.1"
    }
}