Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove camera creation from Observatory #612

Merged
merged 22 commits into from
Sep 27, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
85ffef8
Camera dependency injection.
wtgee Sep 20, 2018
bdd105e
* Removing camera specific tests from observatory
wtgee Sep 20, 2018
7c07fc2
* Add/remove camera methods
wtgee Sep 20, 2018
b9a2e1e
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 20, 2018
0088074
* `config` is option for `create_cameras_from_config`, in which cases
wtgee Sep 20, 2018
ea99f15
Fix old docstring
wtgee Sep 20, 2018
19e81df
More docstring fixes
wtgee Sep 20, 2018
8d5a9ac
Small cleanup
wtgee Sep 20, 2018
ed5e115
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 20, 2018
e56465a
* Return an empty OrderedDict if no camera confiration present
wtgee Sep 20, 2018
0d5efcb
Moving `list_connected_cameras` into cameras file.
wtgee Sep 20, 2018
46d36be
Responding to PR feedback
wtgee Sep 21, 2018
df3d577
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 21, 2018
81cc3b3
Fix import after moving util function
wtgee Sep 21, 2018
4cf2034
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 22, 2018
2e8780e
Cleanup of docstrings
wtgee Sep 22, 2018
da3f59c
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 23, 2018
56a1797
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 26, 2018
d47bcfa
Merge branch 'develop' of https://github.com/panoptes/POCS into camer…
wtgee Sep 26, 2018
bc8fca3
Better debug output from camera creation
wtgee Sep 26, 2018
867cb08
Remove old comment
wtgee Sep 26, 2018
831c04b
Bumping version for camera dependency injection
wtgee Sep 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 42 additions & 13 deletions pocs/camera/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from collections import OrderedDict
import re
import shutil
import subprocess

from pocs.utils import error
from pocs.utils import load_module
Expand All @@ -7,29 +10,55 @@
from pocs.camera.camera import AbstractCamera # pragma: no flakes
from pocs.camera.camera import AbstractGPhotoCamera # pragma: no flakes

from pocs.utils import list_connected_cameras
from pocs.utils import logger as logger_module


def create_cameras_from_config(config=None, logger=None, **kwargs):
"""Creates a camera object(s)
def list_connected_cameras():
"""Detect connected cameras.

Uses gphoto2 to try and detect which cameras are connected. Cameras should
be known and placed in config but this is a useful utility.

Returns:
list: A list of the ports with detected cameras.
"""

gphoto2 = shutil.which('gphoto2')
command = [gphoto2, '--auto-detect']
result = subprocess.check_output(command)
lines = result.decode('utf-8').split('\n')

Loads the cameras via the configuration.
ports = []

for line in lines:
camera_match = re.match(r'([\w\d\s_\.]{30})\s(usb:\d{3},\d{3})', line)
if camera_match:
# camera_name = camera_match.group(1).strip()
port = camera_match.group(2).strip()
ports.append(port)

return ports


def create_cameras_from_config(config=None, logger=None, **kwargs):
"""Create camera object(s) based on the config.

Creates a camera for each camera item listed in the config. Ensures the
appropriate camera module is loaded.

Note:
This does not actually make a connection to the camera. To do so,
call 'camera.connect()' explicitly.
call 'camera.connect()' explicitly on each camera.
Copy link
Collaborator

@AnthonyHorton AnthonyHorton Sep 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is true, yet. All the existing camera classes (and associated focuser classes) call their own connect() method from their __init__(). I think you know that though, because I didn't spot any calls of camera.connect() in the diff!

On a related note, those calls to camera.connect() should be done in parallel as for some of the supported hardware that triggers an initialisation process that takes quite a while and we can significantly speed up startup by doing all the cameras at the same time.


Args:
**kwargs (dict): Can pass a `cameras` object that overrides the info in
the configuration file. Can also pass `auto_detect`(bool) to try and
automatically discover the ports.

Returns:
OrderedDict: An ordered dictionary of created camera objects.
OrderedDict: An ordered dictionary of created camera objects, with the
camera name as key and camera instance as value. Returns an empty
OrderedDict if there is no camera configuration items.
AnthonyHorton marked this conversation as resolved.
Show resolved Hide resolved

Raises:
error.CameraNotFound: Description
Expand All @@ -41,20 +70,21 @@ def create_cameras_from_config(config=None, logger=None, **kwargs):
if not config:
config = load_config(**kwargs)

if 'cameras' not in config:
logger.info('No camera information in config.')
return None

# Helper method to first check kwargs then config
def kwargs_or_config(item, default=None):
return kwargs.get(item, config.get(item, default))

cameras = OrderedDict()
camera_info = kwargs_or_config('cameras')
a_simulator = 'camera' in kwargs_or_config('simulator', default=list())
auto_detect = kwargs_or_config('auto_detect', default=False)
if not camera_info:
logger.info('No camera information in config.')
return cameras

logger.debug("Camera config: {}".format(camera_info))

a_simulator = 'camera' in kwargs_or_config('simulator', default=list())
auto_detect = kwargs_or_config('auto_detect', default=False)

ports = list()

# Lookup the connected ports if not using a simulator
Expand All @@ -71,7 +101,6 @@ def kwargs_or_config(item, default=None):
else:
logger.debug("Detected Ports: {}".format(ports))

cameras = OrderedDict()
primary_camera = None

device_info = camera_info['devices']
Expand Down
2 changes: 1 addition & 1 deletion pocs/tests/utils/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@


from pocs.utils import current_time
from pocs.utils import list_connected_cameras
from pocs.utils import listify
from pocs.utils import load_module
from pocs.utils.error import NotFound
from pocs.camera import list_connected_cameras


def test_bad_load_module():
Expand Down
25 changes: 0 additions & 25 deletions pocs/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import os
import re
import shutil
import subprocess
import time

from astropy import units as u
Expand Down Expand Up @@ -119,29 +117,6 @@ def get_free_space(dir=None):
return free_space


def list_connected_cameras():
"""
Uses gphoto2 to try and detect which cameras are connected.
Cameras should be known and placed in config but this is a useful utility.
"""

gphoto2 = shutil.which('gphoto2')
command = [gphoto2, '--auto-detect']
result = subprocess.check_output(command)
lines = result.decode('utf-8').split('\n')

ports = []

for line in lines:
camera_match = re.match('([\w\d\s_\.]{30})\s(usb:\d{3},\d{3})', line)
if camera_match:
# camera_name = camera_match.group(1).strip()
port = camera_match.group(2).strip()
ports.append(port)

return ports


def load_module(module_name):
""" Dynamically load a module

Expand Down