@Cam Camera Bridges
===================

A bridge is a small program that lets @Cam use a camera it has no driver for.
The bridge controls the camera through the maker's own software (its SDK) and
serves the camera's controls and images to @Cam. @Cam then treats it like any
other camera.

Connecting a real camera takes some programming: you write the part that
talks to your camera. Trying the simulated camera below takes none.

The files in this folder:

  atcam_bridge.py   A Python library for writing a bridge, and a simulated
                    camera to try it with
  PROTOCOL.md       The full description of how a bridge talks to @Cam, for
                    writing one in any language
  LICENSE.txt       You may use, change, and share these files (MIT license)


TRY THE SIMULATED CAMERA
------------------------

You need Python 3.9 or later. The numpy package is optional; with it, the
simulated camera is faster and offers more pixel formats.

1. Open Terminal and go to this folder. Type cd and a space, drag the folder
   onto the Terminal window, and press Return.

2. Start the bridge:

       python3 atcam_bridge.py

3. Open @Cam and choose "Simulated camera" from the camera menu. If macOS
   asks, allow @Cam to find devices on the local network.

   If it isn't listed, go to @Cam > Settings > Cameras > Camera Bridges and
   add localhost:48620.

The bridge must keep running while you use the camera. Press Control-C in
Terminal to stop it.

Options:

  --name "Bench camera"   The name shown in @Cam's camera menu
  --port 5000             Use another port (the default is 48620)
  --host 127.0.0.1        Accept connections from this computer only
  --no-bonjour            Don't announce the bridge; add its address in @Cam
  --quiet                 Don't print messages


BRIDGE A REAL CAMERA
--------------------

1. Install the camera maker's SDK on the computer connected to the camera,
   and confirm that you can grab an image with it from Python.

2. In a new Python file next to atcam_bridge.py, subclass Camera: list the
   camera's controls and return its images from grab().

       from atcam_bridge import Camera, Feature, serve

       class MyCamera(Camera):
           name = "My camera"
           width, height = 1280, 1024

           def __init__(self):
               super().__init__()
               self.add(Feature("ExposureTime", "float", 20000.0,
                                label="Exposure time", category="Exposure",
                                unit="us", min=100.0, max=1000000.0, log=True,
                                on_set=self.set_exposure))

           def set_exposure(self, value):
               # Set the exposure through the maker's SDK here, and return
               # the value the camera actually applied.
               return value

           def grab(self):
               # Wait for the next image from the maker's SDK here.
               pixels = bytes(self.width * self.height)  # a black test image
               return pixels, self.width, self.height, "Mono8", 0

       serve(MyCamera())

   grab() returns the pixels, width, height, pixel format, and a timestamp in
   nanoseconds (0 if unknown), and it should wait until the camera has a new
   image. This example has no wait, so it sends black images as fast as it
   can; replace it before you use it.

3. Run your file, and choose the camera in @Cam.

Use standard control names such as ExposureTime and Gain where they fit, and
@Cam shows them in its usual tabs, with friendly labels. Other controls appear
in the All Settings tab. PROTOCOL.md lists the names and the pixel formats.

The bridge doesn't have to be written in Python. If the maker's SDK suits
another language better, PROTOCOL.md has everything you need.


RUN A BRIDGE ON ANOTHER COMPUTER
--------------------------------

A bridge can run on another computer, such as one with a camera whose
software doesn't run on a Mac. Start it there, and on your Mac add
the computer's address under @Cam > Settings > Cameras > Camera Bridges, as
hostname:48620 or 192.168.1.20:48620. Allow the port through that computer's
firewall if it blocks it.

The connection is neither encrypted nor password protected. By default, a
bridge accepts connections from any computer that can reach it, and anyone
connected can see the images and change the camera's settings. Run bridges
only on a network you trust, and use --host 127.0.0.1 when @Cam is on the
same computer.


These files are provided as is, without warranty (see LICENSE.txt).
