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

Massive commit of decoupling from mongo and addinng a PanFileDB type #414

Merged
merged 14 commits into from
Feb 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions bin/peas_shell
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ from peas.webcam import Webcam

from pocs.utils import current_time
from pocs.utils.config import load_config
from pocs.utils.database import PanMongo
from pocs.utils.database import PanDB


class PanSensorShell(cmd.Cmd):
Expand All @@ -27,7 +27,7 @@ class PanSensorShell(cmd.Cmd):
environment = None
weather = None
active_sensors = dict()
db = PanMongo()
db = PanDB()
_keep_looping = False
_loop_delay = 60
_timer = None
Expand Down Expand Up @@ -190,7 +190,7 @@ class PanSensorShell(cmd.Cmd):
port = '/dev/ttyUSB0'

print("Loading AAG Cloud Sensor on {}".format(port))
self.weather = AAGCloudSensor(serial_address=port, use_mongo=True)
self.weather = AAGCloudSensor(serial_address=port, store_result=True)
self.do_enable_sensor('weather')

##################################################################################################
Expand Down Expand Up @@ -353,7 +353,7 @@ class PanSensorShell(cmd.Cmd):
if sensor_name in self.active_sensors:
sensor = getattr(self, sensor_name)
try:
sensor.capture(use_mongo=True, send_message=True)
sensor.capture(store_result=True, send_message=True)
except Exception as e:
pass

Expand Down
6 changes: 3 additions & 3 deletions bin/pocs_shell
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ from pocs.utils.images import fits as fits_utils
from pocs.utils.images import cr2 as cr2_utils
from pocs.utils.images import polar_alignment as polar_alignment_utils
from pocs.utils import listify
from pocs.utils.database import PanMongo
from pocs.utils.database import PanDB
from pocs.utils.messaging import PanMessaging


Expand Down Expand Up @@ -220,7 +220,7 @@ Hardware names: {} (or all for all hardware)'''.format(
status = self.pocs.status()
pprint(status)
print_info('*' * 80)
self.pocs.db.insert_current('system', status, include_collection=False)
self.pocs.db.insert_current('system', status, store_permanently=False)
time.sleep(2)
except KeyboardInterrupt:
print_warning('Stopping collection')
Expand Down Expand Up @@ -813,7 +813,7 @@ def process_img(fn, start_time, remove_after=True):
except Exception:
pass

db = PanMongo()
db = PanDB()

# Add to DB
db.drift_align.insert_one({
Expand Down
1 change: 1 addition & 0 deletions conf_files/pocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ directories:
mounts: POCS/resources/mounts
db:
name: panoptes
type: mongo
Copy link
Contributor

Choose a reason for hiding this comment

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

When should we switch to the new type?

Copy link
Member Author

Choose a reason for hiding this comment

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

I actually want to add an sqlite type and make that the default. I think the flat file is a good alternative but I'm not sure ideal.

scheduler:
type: dispatch
fields_file: simple.yaml
Expand Down
12 changes: 4 additions & 8 deletions peas/sensors.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import json
import os

# Note: list_comports is modified by test_sensors.py, so if changing
# this import, the test will also need to be updated.
from serial.tools.list_ports import comports as list_comports

import sys
import yaml

from pocs.utils.database import PanMongo
from pocs.utils.database import PanDB
from pocs.utils.config import load_config
from pocs.utils.logger import get_root_logger
from pocs.utils.messaging import PanMessaging
Expand Down Expand Up @@ -82,7 +79,7 @@ def send_message(self, msg, channel='environment'):

self.messaging.send_message(channel, msg)

def capture(self, use_mongo=True, send_message=True):
def capture(self, store_result=True, send_message=True):
"""
Helper function to return serial sensor info.

Expand Down Expand Up @@ -121,10 +118,9 @@ def capture(self, use_mongo=True, send_message=True):
except Exception as e:
self.logger.warning('Exception while reading from sensor {}: {}', sensor_name, e)

if use_mongo and len(sensor_data) > 0:
if store_result and len(sensor_data) > 0:
if self.db is None:
self.db = PanMongo()
self.logger.info('Connected to PanMongo')
self.db = PanDB()
self.db.insert_current('environment', sensor_data)

return sensor_data
Expand Down
12 changes: 6 additions & 6 deletions peas/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@


def get_mongodb():
from pocs.utils.database import PanMongo
return PanMongo()
from pocs.utils.database import PanDB
return PanDB()


def movingaverage(interval, window_size):
Expand Down Expand Up @@ -101,7 +101,7 @@ class AAGCloudSensor(object):

"""

def __init__(self, serial_address=None, use_mongo=True):
def __init__(self, serial_address=None, store_result=True):
self.config = load_config(config_files='peas')
self.logger = get_root_logger()

Expand All @@ -111,7 +111,7 @@ def __init__(self, serial_address=None, use_mongo=True):
self.safety_delay = self.cfg.get('safety_delay', 15.)

self.db = None
if use_mongo:
if store_result:
self.db = get_mongodb()

self.messaging = None
Expand Down Expand Up @@ -610,7 +610,7 @@ def send_message(self, msg, channel='weather'):

self.messaging.send_message(channel, msg)

def capture(self, use_mongo=False, send_message=False, **kwargs):
def capture(self, store_result=False, send_message=False, **kwargs):
""" Query the CloudWatcher """

self.logger.debug("Updating weather")
Expand Down Expand Up @@ -662,7 +662,7 @@ def capture(self, use_mongo=False, send_message=False, **kwargs):
if send_message:
self.send_message({'data': data}, channel='weather')

if use_mongo:
if store_result:
self.db.insert_current('weather', data)

return data
Expand Down
21 changes: 17 additions & 4 deletions pocs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pocs import hardware
from pocs import __version__
from pocs.utils import config
from pocs.utils.database import PanMongo
from pocs.utils.database import PanDB
from pocs.utils.logger import get_root_logger

# Global vars
Expand Down Expand Up @@ -49,9 +49,22 @@ def __init__(self, *args, **kwargs):

self.config['simulator'] = hardware.get_simulator_names(config=self.config, kwargs=kwargs)

# Set up connection to database
db = kwargs.get('db', self.config['db']['name'])
_db = PanMongo(db=db, logger=self.logger)
# Get passed DB or set up new connection
_db = kwargs.get('db', None)
if _db is None:
# If the user requests a db_type then update runtime config
db_type = kwargs.get('db_type', None)
db_name = kwargs.get('db_name', None)

if db_type is not None:
self.config['db']['type'] = db_type
if db_name is not None:
self.config['db']['name'] = db_name

db_type = self.config['db']['type']
db_name = self.config['db']['name']

_db = PanDB(db_type=db_type, db_name=db_name, logger=self.logger).db

self.db = _db

Expand Down
2 changes: 0 additions & 2 deletions pocs/camera/canon_gphoto2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

from pocs.utils import current_time
from pocs.utils import error
from pocs.utils import images as img_utils
from pocs.utils.images import fits as fits_utils
from pocs.utils.images import cr2 as cr2_utils
from pocs.camera import AbstractGPhotoCamera

Expand Down
1 change: 0 additions & 1 deletion pocs/camera/sbig.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from warnings import warn

from astropy import units as u
from astropy.io import fits

from pocs.camera import AbstractCamera
from pocs.camera.sbigudrv import INVALID_HANDLE_VALUE
Expand Down
6 changes: 3 additions & 3 deletions pocs/camera/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from astropy import units as u
from astropy.io import fits
from astropy.time import Time

from pocs.camera import AbstractCamera
from pocs.utils.images import fits as fits_utils
Expand Down Expand Up @@ -76,8 +75,9 @@ def take_exposure(self, seconds=1.0 * u.second, filename=None, dark=False, block
# Build FITS header
header = self._fits_header(seconds, dark)

# Set up a Timer that will wait for the duration of the exposure then copy a dummy FITS file
# to the specified path and adjust the headers according to the exposure time, type.
# Set up a Timer that will wait for the duration of the exposure then
Copy link
Contributor

Choose a reason for hiding this comment

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

We keep having little formatting/cleanup changes like these inside of bigger changes. Perhaps after this you'd be willing to do another PR that scrubs the whole repo? No need to remove this change from ths PR.

Copy link
Member Author

@wtgee wtgee Feb 3, 2018

Choose a reason for hiding this comment

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

Good idea. I've just been doing them as I see them, which does pollute the PR some.

# copy a dummy FITS file to the specified path and adjust the headers
# according to the exposure time, type.
exposure_event = Event()
exposure_thread = Timer(interval=seconds,
function=self._fake_exposure,
Expand Down
24 changes: 14 additions & 10 deletions pocs/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,7 @@ def power_down(self):
if self.connected:
self.say("I'm powering down")
self.logger.info(
"Shutting down {}, please be patient and allow for exit.".format(
self.name))
"Shutting down {}, please be patient and allow for exit.", self.name)

if not self.observatory.close_dome():
self.logger.critical('Unable to close dome!')
Expand Down Expand Up @@ -347,10 +346,9 @@ def is_weather_safe(self, stale=180):
bool: Conditions are safe (True) or unsafe (False)

"""
assert self.db.current, self.logger.warning(
"No connection to sensors, can't check weather safety")

# Always assume False
self.logger.debug("Checking weather safety")
is_safe = False
record = {'safe': False}

Expand All @@ -366,15 +364,16 @@ def is_weather_safe(self, stale=180):
record = self.db.get_current('weather')

is_safe = record['data'].get('safe', False)
timestamp = record['date']
timestamp = record['date'].replace(tzinfo=None) # current_time is timezone naive
age = (current_time().datetime - timestamp).total_seconds()

self.logger.debug(
"Weather Safety: {} [{:.0f} sec old - {}]".format(is_safe, age, timestamp))

except TypeError as e:
self.logger.warning("No record found in Mongo DB")
self.logger.debug('DB: {}'.format(self.db.current))
except (TypeError, KeyError) as e:
self.logger.warning("No record found in DB: {}", e)
except BaseException as e:
self.logger.error("Error checking weather: {}", e)
else:
if age > stale:
self.logger.warning("Weather record looks stale, marking unsafe.")
Expand Down Expand Up @@ -445,10 +444,11 @@ def wait_until_safe(self):


##################################################################################################
# Private Methods
# Class Methods
##################################################################################################

def _check_environment(self):
@classmethod
def check_environment(cls):
""" Checks to see if environment is set up correctly

There are a number of environmental variables that are expected
Expand Down Expand Up @@ -476,6 +476,10 @@ def _check_environment(self):
print("Creating log dir at {}/logs".format(pandir))
os.makedirs("{}/logs".format(pandir))

##################################################################################################
# Private Methods
##################################################################################################

def _check_messages(self, queue_type, q):
cmd_dispatch = {
'command': {
Expand Down
17 changes: 7 additions & 10 deletions pocs/observatory.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,13 @@ def analyze_recent(self):
self.logger.debug('Offset Info: {}'.format(
self.current_offset_info))

# Update the observation info with the offsets
self.db.observations.update({'data.image_id': image_id}, {
'$set': {
'offset_info': {
'd_ra': self.current_offset_info.delta_ra.value,
'd_dec': self.current_offset_info.delta_dec.value,
'magnitude': self.current_offset_info.magnitude.value,
'unit': 'arcsec'
}
},
# Store the offset information
self.db.insert('offset_info', {
'image_id': image_id,
'd_ra': self.current_offset_info.delta_ra.value,
'd_dec': self.current_offset_info.delta_dec.value,
'magnitude': self.current_offset_info.magnitude.value,
'unit': 'arcsec',
})

except error.SolveError:
Expand Down
36 changes: 32 additions & 4 deletions pocs/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import pocs.base
from pocs import hardware
from pocs.utils.config import load_config
from pocs.utils.database import PanMongo
from pocs.utils.database import PanDB
from pocs.utils.logger import get_root_logger

# Global variable with the default config; we read it once, copy it each time it is needed.
_one_time_config = None
Expand Down Expand Up @@ -76,9 +77,36 @@ def config_with_simulated_dome(config):
return config


@pytest.fixture
def db():
return PanMongo(db='panoptes_testing')
@pytest.fixture(scope='function', params=['mongo', 'file'])
def db(request):
try:
_db = PanDB(
db_type=request.param,
db_name='panoptes_testing',
logger=get_root_logger(),
connect=True
)
except Exception:
pytest.skip("Can't connect to {} DB, skipping".format(request.param))

return _db


@pytest.fixture(scope='function', params=['mongo', 'file'])
def db_type(request):
# If testing mongo, make sure we can connect, otherwise skip
if request.param == 'mongo':
try:
PanDB(
db_type='mongo',
db_name='panoptes_testing',
logger=get_root_logger(),
connect=True
)
except Exception:
pytest.skip("Can't connect to {} DB, skipping".format(request.param))

return request.param


@pytest.fixture
Expand Down
7 changes: 3 additions & 4 deletions pocs/tests/test_messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,12 @@ def test_send_datetime(forwarder, sub, pub):
assert msg_obj['date'] == '2017-01-01T00:00:00'


def test_mongo_objectid(forwarder, sub, pub, config, db):
def test_storage_id(forwarder, sub, pub, config, db):

db.insert_current('config', {'foo': 'bar'})
id0 = db.insert_current('config', {'foo': 'bar'}, store_permanently=False)

pub.send_message('TEST-CHANNEL', db.get_current('config'))
msg_type, msg_obj = sub.receive_message()
assert '_id' in msg_obj
assert isinstance(msg_obj['_id'], str)

db.current.remove({'type': 'config'})
assert id0 == msg_obj['_id']
Loading