Skip to content

sony

plantimager.sony Link

Camera Link

Camera(device_ip, api_port, timeout=10, postview=False, use_adb=False, use_flashair=False, flashair_host=None, camera_params=None, rotation=0)

Bases: AbstractCamera

Sony Remote Control API.

Provides a high‑level interface to a Sony camera over the network, allowing image capture and optional post‑processing such as rotation. Images are returned as plantimager.hal.DataItem objects with an rgb channel containing a NumPy array.

Attributes:

Name Type Description
sony_cam SonyCamAPI

Low‑level API wrapper handling direct camera communication.

postview bool

Flag indicating whether postview mode is active.

use_adb bool

Flag indicating whether ADB transfer is used.

use_flashair bool

Flag indicating whether FlashAir transfer is used.

flashair (FlashAirAPI, optional)

Instance of ~plantimager.sony.FlashAirAPI when use_flashair is True.

camera_params dict or None

Camera configuration dictionary passed to SonyCamAPI.setup_camera.

rotation int

Rotation angle (degrees counter‑clockwise) applied to images.

Raises:

Type Description
SonyCamError

If both use_flashair and use_adb are True or if use_flashair is True but flashair_host is not provided.

See Also

SonyCamAPI : Low‑level API for Sony camera commands. FlashAirAPI : API for interacting with a FlashAir Wi‑Fi SD card.

Examples:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from plantimager.sony import Camera
>>> # Capture a low‑resolution image using postview mode (Sony RX0):
>>> cam = Camera('192.168.122.1', '10000', postview=True, rotation=0)
>>> img = cam.grab(0)
>>> arr = img.channels['rgb'].data
>>> print(arr.shape)
(1440, 1080, 3)
>>> # Visualize the capture image:
>>> plt.imshow(arr)
>>> plt.show()
>>> # Capture a rotated low‑resolution image using postview mode (Sony RX0):
>>> cam = Camera('192.168.122.1', '10000', postview=True, rotation=270)
>>> img = cam.grab(0)
>>> arr = np.array(img.channels['rgb'].data)
>>> print(arr.shape)
(1080, 1440, 3)
>>> # Visualize the capture image:
>>> plt.imshow(arr)
>>> plt.show()

Constructor.

Parameters:

Name Type Description Default
device_ip str

IP address of the Sony camera.

required
api_port str

Port number of the camera's API endpoint.

required
timeout time_s

Network timeout (in seconds) for API calls. Default is 10.

10
postview bool

If True, download the low‑resolution postview image directly from the camera. False uses a full‑resolution download path.

False
use_adb bool

Use Android Debug Bridge (ADB) to transfer the picture. Mutually exclusive with use_flashair.

False
use_flashair bool

Use a Wi‑Fi SD card (FlashAir) to transfer the picture. Mutually exclusive with use_adb.

False
flashair_host str

Host IP of the FlashAir device. Required when use_flashair is True.

None
camera_params dict

Dictionary of camera settings that are applied after entering shoot mode.

None
rotation int

Counter‑clockwise rotation (in degrees) applied to the captured image. Only multiples of 90° are supported; other values are reduced modulo 360.

0
Source code in plantimager/sony.py
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
def __init__(self, device_ip: str,
             api_port: str,
             timeout: time_s = 10,
             postview: bool = False,
             use_adb: bool = False,
             use_flashair: bool = False,
             flashair_host: str = None,
             camera_params: dict = None,
             rotation: int = 0):
    """Constructor.

    Parameters
    ----------
    device_ip : str
        IP address of the Sony camera.
    api_port : str
        Port number of the camera's API endpoint.
    timeout : time_s, optional
        Network timeout (in seconds) for API calls. Default is ``10``.
    postview : bool, optional
        If ``True``, download the low‑resolution postview image directly from the camera.
        ``False`` uses a full‑resolution download path.
    use_adb : bool, optional
        Use Android Debug Bridge (ADB) to transfer the picture.
        Mutually exclusive with ``use_flashair``.
    use_flashair : bool, optional
        Use a Wi‑Fi SD card (FlashAir) to transfer the picture.
        Mutually exclusive with ``use_adb``.
    flashair_host : str, optional
        Host IP of the FlashAir device. Required when ``use_flashair`` is ``True``.
    camera_params : dict, optional
        Dictionary of camera settings that are applied after entering shoot mode.
    rotation : int, optional
        Counter‑clockwise rotation (in degrees) applied to the captured image.
        Only multiples of 90° are supported; other values are reduced modulo 360.
    """
    self.sony_cam = SonyCamAPI(device_ip, api_port, timeout=timeout)
    self.postview = postview
    self.use_flashair = use_flashair
    self.use_adb = use_adb
    if use_flashair and use_adb:
        raise SonyCamError("Cannot use both flashair and adb for transfer")
    if use_flashair:
        if flashair_host is None:
            raise SonyCamError("Must provide flashair host IP")
        self.flashair = FlashAirAPI(flashair_host)

    self.camera_params = camera_params
    self.rotation = rotation  # degrees counter-clockwise
    self.start()

grab Link

grab(idx, metadata=None)

Capture a single image from the Sony camera.

Parameters:

Name Type Description Default
idx int

Index assigned to the returned ~plantimager.hal.DataItem. Useful for sequencing images when multiple captures are performed.

required
metadata dict

Arbitrary user‑defined metadata that will be attached to the resulting ~plantimager.hal.DataItem. If None an empty metadata dictionary is created.

None

Returns:

Type Description
DataItem

A data container with an rgb channel holding the captured image as a NumPy ndarray. The channel can be accessed via item.channels['rgb'].data.

Raises:

Type Description
SonyCamError
  • If both use_adb and use_flashair are enabled (checked at construction time).
  • If the camera is in a state that prevents picture capture (e.g., ContentsTransfer mode).
  • If any network request (HTTP or ADB) fails.
Notes
  • The method chooses the image transfer mechanism in the following priority order:
    1. Postview – low‑resolution image retrieved directly from the camera URL.
    2. ADB – uses Android Debug Bridge to pull the latest image from the camera’s internal storage.
    3. FlashAir – pulls the latest image from a Wi‑Fi SD card.
    4. File‑transfer mode – switches the camera to Contents Transfer mode and downloads the full‑resolution image via HTTP.
  • If rotation is non‑zero, the image is rotated counter‑clockwise in multiples of 90°.
Source code in plantimager/sony.py
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
def grab(self, idx: int, metadata: dict = None) -> DataItem:
    """Capture a single image from the Sony camera.

    Parameters
    ----------
    idx : int
        Index assigned to the returned `~plantimager.hal.DataItem`.
        Useful for sequencing images when multiple captures are performed.
    metadata : dict, optional
        Arbitrary user‑defined metadata that will be attached to the resulting `~plantimager.hal.DataItem`.
        If ``None`` an empty metadata dictionary is created.

    Returns
    -------
    DataItem
        A data container with an ``rgb`` channel holding the captured image as a NumPy ``ndarray``.
        The channel can be accessed via ``item.channels['rgb'].data``.

    Raises
    ------
    SonyCamError
        * If both ``use_adb`` and ``use_flashair`` are enabled (checked at construction time).
        * If the camera is in a state that prevents picture capture (e.g., ``ContentsTransfer`` mode).
        * If any network request (HTTP or ADB) fails.

    Notes
    -----
    * The method chooses the image transfer mechanism in the following priority order:
        1. **Postview** – low‑resolution image retrieved directly from the camera URL.
        2. **ADB** – uses Android Debug Bridge to pull the latest image from the camera’s internal storage.
        3. **FlashAir** – pulls the latest image from a Wi‑Fi SD card.
        4. **File‑transfer mode** – switches the camera to *Contents Transfer* mode and downloads the
           full‑resolution image via HTTP.
    * If ``rotation`` is non‑zero, the image is rotated counter‑clockwise in multiples of 90°.
    """
    data_item = DataItem(idx, metadata)
    res = self.sony_cam.take_picture()
    url = res[0]
    if self.postview:  # Download image from postview
        data = imageio.imread(BytesIO(requests.get(url).content))
    elif self.use_adb:  # Download using android debug
        images = self.sony_cam.adb_transfer_pictures(count=1)
        data = images[0]
    elif self.use_flashair:  # Download on wifi sd card
        images = self.flashair.transfer_latest_pictures(count=1)
        data = images[0]
    else:  # Download using file transfer mode (not available on all cameras)
        self.sony_cam.start_transfer_mode()
        uri = self.sony_cam.get_source_list()[0]['source']
        content_list = self.sony_cam.get_content_list(count=1, uri=uri)
        content = content_list[0]
        content = content['content']['original'][0]
        url = content['url']
        data = imageio.imread(BytesIO(requests.get(url).content))
        self.sony_cam.start_shoot_mode()

    if self.rotation != 0:
        # Rotate using NumPy for multiples of 90 degrees (counter‑clockwise)
        # k = number of 90° rotations
        k = (self.rotation // 90) % 4
        data = np.rot90(data, k=k)

    data_item.add_channel('rgb', data)
    return data_item

start Link

start()

Initialize the camera for shooting.

Raises:

Type Description
SonyCamError

If the camera cannot be switched to shoot mode or if a configuration command fails.

Source code in plantimager/sony.py
671
672
673
674
675
676
677
678
679
680
681
682
def start(self):
    """Initialize the camera for shooting.

    Raises
    ------
    SonyCamError
        If the camera cannot be switched to shoot mode or if a configuration command fails.
    """
    self.sony_cam.start_shoot_mode()
    self.sony_cam.set_shoot_mode("still")
    if self.camera_params is not None:
        self.sony_cam.setup_camera(self.camera_params)

SonyCamAPI Link

SonyCamAPI(device_ip, api_port, timeout=2)

Bases: object

High‑level Python wrapper for Sony Camera HTTP API.

This class abstracts the low‑level JSON‑RPC calls required to control a Sony camera over the network. It provides convenience methods for common actions such as starting recording mode, taking a picture, querying status, and transferring images via ADB.

Attributes:

Name Type Description
device_ip str

Stored IP address of the camera.

api_port str

Stored API port.

api_url str

Base URL built from device_ip and api_port.

timeout float

Timeout used for requests.post calls.

supported_methods list of str

List of method names supported by the camera, retrieved during initialization via get_method_types.

Constructor.

Parameters:

Name Type Description Default
device_ip str

IP address of the camera (e.g., '192.168.1.10').

required
api_port str

Port on which the camera's API service is listening (usually '80').

required
timeout float

Network timeout in seconds for each HTTP request.

``2.0``
Source code in plantimager/sony.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def __init__(self, device_ip, api_port, timeout=2):
    """Constructor.

    Parameters
    ----------
    device_ip : str
        IP address of the camera (e.g., ``'192.168.1.10'``).
    api_port : str
        Port on which the camera's API service is listening (usually ``'80'``).
    timeout : float, optional, default ``2.0``
        Network timeout in seconds for each HTTP request.
    """
    self.device_ip = device_ip
    self.api_port = api_port
    self.api_url = 'http://' + device_ip + ':' + api_port + '/sony/'
    self.timeout = timeout
    method_types = self.get_method_types()
    self.supported_methods = [x[0] for x in method_types]

adb_transfer_pictures Link

adb_transfer_pictures(count=1)

Transfer the latest count pictures from the camera via ADB.

Parameters:

Name Type Description Default
count int

Number of most‑recent images to pull.

``1``

Returns:

Type Description
list of numpy.ndarray

Loaded images as NumPy arrays.

Notes
  • ADB shell must be enabled on the camera.
  • Images are temporarily stored in /tmp/ before being read with imageio.imread.
  • The method prints each filename as it is transferred.
Source code in plantimager/sony.py
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
def adb_transfer_pictures(self, count=1):
    """Transfer the latest ``count`` pictures from the camera via ADB.

    Parameters
    ----------
    count : int, optional, default ``1``
        Number of most‑recent images to pull.

    Returns
    -------
    list of numpy.ndarray
        Loaded images as NumPy arrays.

    Notes
    -----
    - ADB shell must be enabled on the camera.
    - Images are temporarily stored in ``/tmp/`` before being read with ``imageio.imread``.
    - The method prints each filename as it is transferred.
    """
    # Connect (ignore "already connected" noise)
    try:
        subprocess.run(
            ["adb", "connect", self.device_ip],
            check=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            timeout=15,
        )
    except subprocess.CalledProcessError as exc:
        raise RuntimeError(f"Failed to connect to device {self.device_ip}") from exc

    # List files sorted by modification time (using `ls -t`)
    result = subprocess.run(
        ["adb", "shell", "ls", "-t", "/sdcard/DCIM/100MSDCF"],
        capture_output=True,
        text=True,
        check=True,
        timeout=15,
    )
    files = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    files = files[:count]  # newest first

    images: list[np.ndarray] = []
    with tempfile.TemporaryDirectory() as tmp_dir:
        for f in files:
            # Pull safely
            subprocess.run(
                ["adb", "pull", f"/sdcard/DCIM/100MSDCF/{f}", tmp_dir],
                check=True,
                timeout=30,
            )
            img_path = os.path.join(tmp_dir, f)
            images.append(imageio.imread(img_path))
            logger.info("Pulled %s", f)

    return images

api_call Link

api_call(endpoint, method, params=[], version='1.0')

Perform a JSON‑RPC call to the Sony camera.

Parameters:

Name Type Description Default
endpoint str

API endpoint (e.g., 'camera' or 'avContent').

required
method str

Remote method name to invoke.

required
params list

Positional parameters for the remote method.

``[]``
version str

API version string.

``'1.0'``

Returns:

Type Description
list or dict

The 'result' or 'results' field from the JSON response. Returns an empty dict if the response contains neither.

Raises:

Type Description
SonyCamError

If the remote API returns an 'error' field.

Notes

The method serialises params to JSON and sends a POST request. It decodes the response as UTF‑8 before parsing.

Source code in plantimager/sony.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def api_call(self, endpoint, method, params=[], version='1.0'):
    """Perform a JSON‑RPC call to the Sony camera.

    Parameters
    ----------
    endpoint : str
        API endpoint (e.g., ``'camera'`` or ``'avContent'``).
    method : str
        Remote method name to invoke.
    params : list, optional, default ``[]``
        Positional parameters for the remote method.
    version : str, optional, default ``'1.0'``
        API version string.

    Returns
    -------
    list or dict
        The ``'result'`` or ``'results'`` field from the JSON response.
        Returns an empty ``dict`` if the response contains neither.

    Raises
    ------
    SonyCamError
        If the remote API returns an ``'error'`` field.

    Notes
    -----
    The method serialises ``params`` to JSON and sends a POST request.
    It decodes the response as UTF‑8 before parsing.
    """
    request_result = requests.post(self.api_url + endpoint,
                                   data=json.dumps({
                                       'method': method,
                                       'params': params,
                                       'id': 1,
                                       'version': version
                                   }),
                                   timeout=self.timeout)
    res = json.loads(request_result.content.decode('utf-8'))
    if 'error' in res:
        err = res['error']
        raise SonyCamError('''
        Failed camera request.
        Exception code: %d
        Description: %s
        ''' % (err[0], err[1]))
    if 'result' in res:
        return res['result']
    if 'results' in res:
        return res['results']
    return {}

get_available_api_list Link

get_available_api_list()

List all API categories supported by the camera.

Returns:

Type Description
list of str

API categories (e.g., ['camera', 'avContent']).

Source code in plantimager/sony.py
275
276
277
278
279
280
281
282
283
def get_available_api_list(self) -> list[str]:
    """List all API categories supported by the camera.

    Returns
    -------
    list of str
        API categories (e.g., ``['camera', 'avContent']``).
    """
    return self.api_call("camera", "getAvailableApiList")[0]

get_available_camera_function Link

get_available_camera_function()

Retrieve the list of camera functions supported by the device.

Source code in plantimager/sony.py
185
186
187
def get_available_camera_function(self) -> list[str]:
    """Retrieve the list of camera functions supported by the device."""
    return self.api_call("camera", "getAvailableCameraFunction")[0]

get_available_shoot_mode Link

get_available_shoot_mode()

Return the list of supported shoot modes.

Returns:

Type Description
list of str

Available shoot modes (e.g., ['still', 'movie']).

Source code in plantimager/sony.py
380
381
382
383
384
385
386
387
def get_available_shoot_mode(self) -> list[str]:
    """Return the list of supported shoot modes.

    Returns
    -------
    list of str
        Available shoot modes (e.g., ``['still', 'movie']``)."""
    return self.api_call("camera", "getAvailableShootMode")[1]

get_camera_function Link

get_camera_function()

Get the currently selected camera function.

Source code in plantimager/sony.py
189
190
191
def get_camera_function(self) -> str:
    """Get the currently selected camera function."""
    return self.api_call("camera", "getCameraFunction")[0]

get_camera_status Link

get_camera_status()

Obtain the current camera status from the event stream.

Returns:

Type Description
str

Status string such as 'IDLE', 'ContentsTransfer', etc.

Raises:

Type Description
SonyCamError

If the status cannot be extracted from the event list.

Source code in plantimager/sony.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
def get_camera_status(self) -> str:
    """Obtain the current camera status from the event stream.

    Returns
    -------
    str
        Status string such as ``'IDLE'``, ``'ContentsTransfer'``, etc.

    Raises
    ------
    SonyCamError
        If the status cannot be extracted from the event list.
    """
    events = self.get_event()
    for x in events:
        if 'cameraStatus' in x:
            return x['cameraStatus']
    raise SonyCamError('Could not get camera status')

get_content_list Link

get_content_list(count, uri, stIdx=0, view='flat', sort='descending')

List media content under a specific uri.

Parameters:

Name Type Description Default
count int

Maximum number of items to return.

required
uri str

Base URI of the content container (e.g., 'storage:memory').

required
stIdx int

Starting index for pagination.

``0``
view str

View mode; 'flat' returns a flat list.

``'flat'``
sort str

Sort order of results.

``'descending'``

Returns:

Type Description
list of dict

Content entries matching the query.

Source code in plantimager/sony.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
def get_content_list(self, count, uri, stIdx=0, view="flat", sort="descending") -> list[dict]:
    """List media content under a specific ``uri``.

    Parameters
    ----------
    count : int
        Maximum number of items to return.
    uri : str
        Base URI of the content container (e.g., ``'storage:memory'``).
    stIdx : int, optional, default ``0``
        Starting index for pagination.
    view : str, optional, default ``'flat'``
        View mode; ``'flat'`` returns a flat list.
    sort : str, optional, default ``'descending'``
        Sort order of results.

    Returns
    -------
    list of dict
        Content entries matching the query.
    """
    return self.api_call("avContent", "getContentList", [{
        "uri": uri,
        "stIdx": stIdx,
        "cnt": count,
        "view": view,
        "sort": sort}], version="1.3")[0]

get_event Link

get_event(long_polling=False, version='1.0')

Poll the camera for events.

Parameters:

Name Type Description Default
long_polling bool

If True, the call blocks until an event occurs.

``False``
version str

API version for the getEvent request.

``'1.0'``

Returns:

Type Description
list of dict

Event dictionaries returned by the camera.

Source code in plantimager/sony.py
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
def get_event(self, long_polling=False, version="1.0"):
    """Poll the camera for events.

    Parameters
    ----------
    long_polling : bool, optional, default ``False``
        If ``True``, the call blocks until an event occurs.
    version : str, optional, default ``'1.0'``
        API version for the ``getEvent`` request.

    Returns
    -------
    list of dict
        Event dictionaries returned by the camera.
    """
    return self.api_call("camera", "getEvent", [long_polling], version=version)

get_method_types Link

get_method_types(version='1.0')

Retrieve supported method names and their signatures.

Parameters:

Name Type Description Default
version str

API version for the getMethodTypes call.

``'1.0'``

Returns:

Type Description
list of tuple

Each tuple contains (method_name, method_type).

Source code in plantimager/sony.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
def get_method_types(self, version="1.0") -> list[tuple[str, str]]:
    """Retrieve supported method names and their signatures.

    Parameters
    ----------
    version : str, optional, default ``'1.0'``
        API version for the ``getMethodTypes`` call.

    Returns
    -------
    list of tuple
        Each tuple contains ``(method_name, method_type)``.
    """
    return self.api_call("camera", "getMethodTypes", [version])

get_source_list Link

get_source_list()

Retrieve a list of available storage sources.

Returns:

Type Description
list of dict

Each entry describes a storage source (e.g., {'scheme': 'storage', ...}).

Source code in plantimager/sony.py
218
219
220
221
222
223
224
225
226
def get_source_list(self) -> list[dict]:
    """Retrieve a list of available storage sources.

    Returns
    -------
    list of dict
        Each entry describes a storage source (e.g., ``{'scheme': 'storage', ...}``).
    """
    return self.api_call("avContent", "getSourceList", [{"scheme": "storage"}])[0]

get_storage_information Link

get_storage_information()

Query storage details such as free space and total capacity.

Returns:

Type Description
dict

Storage information dictionary as defined by the Sony API.

Source code in plantimager/sony.py
208
209
210
211
212
213
214
215
216
def get_storage_information(self) -> dict:
    """Query storage details such as free space and total capacity.

    Returns
    -------
    dict
        Storage information dictionary as defined by the Sony API.
    """
    return self.api_call("camera", "getStorageInformation")[0]

set_camera_function Link

set_camera_function(function)

Set the active camera function.

Parameters:

Name Type Description Default
function str

Desired camera function (e.g., 'still' or 'movie').

required

Returns:

Type Description
str

Confirmation string returned by the API.

Source code in plantimager/sony.py
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def set_camera_function(self, function) -> str:
    """Set the active camera function.

    Parameters
    ----------
    function : str
        Desired camera function (e.g., ``'still'`` or ``'movie'``).

    Returns
    -------
    str
        Confirmation string returned by the API.
    """
    return self.api_call("camera", "setCameraFunction", [function])[0]

set_shoot_mode Link

set_shoot_mode(mode)

Change the current shoot mode.

Parameters:

Name Type Description Default
mode str

Desired shoot mode identifier (must be one of the values returned by get_available_shoot_mode).

required

Returns:

Type Description
str

Confirmation string from the camera.

Source code in plantimager/sony.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
def set_shoot_mode(self, mode) -> str:
    """Change the current shoot mode.

    Parameters
    ----------
    mode : str
        Desired shoot mode identifier (must be one of the values returned by `get_available_shoot_mode`).

    Returns
    -------
    str
        Confirmation string from the camera.
    """
    return self.api_call("camera", "setShootMode", [mode])

setup_camera Link

setup_camera(params)

Configure multiple camera settings in a single call.

Parameters:

Name Type Description Default
params dict

Mapping of setting names to desired values. Recognised keys are: 'FNumber', 'ShutterSpeed', 'IsoSpeedRate', 'WhiteBalance', 'FlashMode', 'FocusMode'.

required
Source code in plantimager/sony.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def setup_camera(self, params) -> None:
    """Configure multiple camera settings in a single call.

    Parameters
    ----------
    params : dict
        Mapping of setting names to desired values. Recognised keys are:
        ``'FNumber'``, ``'ShutterSpeed'``, ``'IsoSpeedRate'``,
        ``'WhiteBalance'``, ``'FlashMode'``, ``'FocusMode'``.
    """
    if 'FNumber' in params:
        self.api_call('camera', 'setFNumber', [params['FNumber']])
    if 'ShutterSpeed' in params:
        self.api_call('camera', 'setShutterSpeed', [params['ShutterSpeed']])
    if 'IsoSpeedRate' in params:
        self.api_call('camera', 'setIsoSpeedRate', [params['IsoSpeedRate']])
    if 'WhiteBalance' in params:
        self.api_call('camera', 'setWhiteBalance', [params['WhiteBalance']])
    if 'FlashMode' in params:
        self.api_call('camera', 'setFlashMode', [params['FlashMode']])
    if 'FocusMode' in params:
        self.api_call('camera', 'setFocusMode', [params['FocusMode']])

start_movie_rec Link

start_movie_rec()

Begin video recording.

Returns:

Type Description
list

Result payload from the startMovieRec API call.

Source code in plantimager/sony.py
404
405
406
407
408
409
410
411
412
def start_movie_rec(self):
    """Begin video recording.

    Returns
    -------
    list
        Result payload from the ``startMovieRec`` API call.
    """
    return self.api_call("camera", "startMovieRec")

start_rec_mode Link

start_rec_mode()

Switch the camera to recording mode.

Returns:

Type Description
list

The raw result returned by the startRecMode API call.

Raises:

Type Description
SonyCamError

Propagated from :meth:api_call if the request fails.

Source code in plantimager/sony.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def start_rec_mode(self):
    """Switch the camera to recording mode.

    Returns
    -------
    list
        The raw result returned by the ``startRecMode`` API call.

    Raises
    ------
    SonyCamError
        Propagated from :meth:`api_call` if the request fails.
    """
    return self.api_call("camera", "startRecMode")

start_shoot_mode Link

start_shoot_mode()

Prepare the camera for still‑image shooting.

This method ensures the camera function is set to shooting mode and switches to recording mode if required. It blocks until the camera reports 'IDLE' status.

Raises:

Type Description
SonyCamError

Propagated from underlying API calls.

Source code in plantimager/sony.py
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
def start_shoot_mode(self):
    """Prepare the camera for still‑image shooting.

    This method ensures the camera function is set to shooting mode and switches to recording mode if required.
    It blocks until the camera reports ``'IDLE'`` status.

    Raises
    ------
    SonyCamError
        Propagated from underlying API calls.
    """
    if ('setCameraFunction' in self.supported_methods and
            'getCameraFunction' in self.supported_methods):
        camera_function = self.get_camera_function()
        if camera_function != CAMERA_FUNCTION_SHOOT:
            self.set_camera_function(CAMERA_FUNCTION_SHOOT)
    if 'startRecMode' in self.supported_methods:
        self.start_rec_mode()
    while not self.get_camera_status() == 'IDLE':
        continue

start_transfer_mode Link

start_transfer_mode()

Switch the camera to 'ContentsTransfer' mode for bulk download.

The method sets the camera function to transfer mode (if supported) and blocks until the device reports 'ContentsTransfer' status.

Raises:

Type Description
SonyCamError

Propagated from underlying API calls.

Source code in plantimager/sony.py
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
def start_transfer_mode(self):
    """Switch the camera to ``'ContentsTransfer'`` mode for bulk download.

    The method sets the camera function to transfer mode (if supported) and
    blocks until the device reports ``'ContentsTransfer'`` status.

    Raises
    ------
    SonyCamError
        Propagated from underlying API calls.
    """
    if ('setCameraFunction' in self.supported_methods and
            'getCameraFunction' in self.supported_methods):
        camera_function = self.get_camera_function()
        if camera_function != CAMERA_FUNCTION_TRANSFER:
            self.set_camera_function(CAMERA_FUNCTION_TRANSFER)
    while not self.get_camera_status() == 'ContentsTransfer':
        continue

stop_movie_rec Link

stop_movie_rec()

Stop an ongoing video recording.

Returns:

Type Description
list

Result payload from the stopMovieRec API call.

Source code in plantimager/sony.py
414
415
416
417
418
419
420
421
422
def stop_movie_rec(self):
    """Stop an ongoing video recording.

    Returns
    -------
    list
        Result payload from the ``stopMovieRec`` API call.
    """
    return self.api_call("camera", "stopMovieRec")

take_picture Link

take_picture()

Capture a single still image.

The method polls the camera status until it becomes 'IDLE'. If the camera is in 'ContentsTransfer' mode, a SonyCamError is raised.

Returns:

Type Description
str

URL or file identifier of the captured picture (first element of the API actTakePicture result).

Raises:

Type Description
SonyCamError

If the camera is in content‑transfer mode or if the request fails.

Source code in plantimager/sony.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def take_picture(self):
    """Capture a single still image.

    The method polls the camera status until it becomes ``'IDLE'``.
    If the camera is in ``'ContentsTransfer'`` mode, a `SonyCamError` is raised.

    Returns
    -------
    str
        URL or file identifier of the captured picture (first element of the API ``actTakePicture`` result).

    Raises
    ------
    SonyCamError
        If the camera is in content‑transfer mode or if the request fails.
    """
    while True:
        status = self.get_camera_status()
        if status == 'ContentsTransfer':
            raise SonyCamError('Camera is in content transfer mode, cannot take picture')
        elif status == 'IDLE':
            break
        else:
            time.sleep(0.1)

    return self.api_call("camera", "actTakePicture")[0]