예제 #1
0
def main() -> None:
    # -------------------------------------------------------------------------
    # Arguments
    # -------------------------------------------------------------------------
    parser = argparse.ArgumentParser(
        description="test_mimic_balance -- to test Starfeeder",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
        # formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(
        #     prog, max_help_position=30, width=120)
        # http://stackoverflow.com/questions/5462873/control-formatting-of-the-argparse-help-argument-list  # noqa
    )
    parser.add_argument('--verbose',
                        '-v',
                        action='store_true',
                        help="Be verbose")
    add_serial_port_args(parser)
    args = parser.parse_args()
    # -------------------------------------------------------------------------
    # Logging
    # -------------------------------------------------------------------------
    loglevel = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT, level=loglevel)
    rootlogger = logging.getLogger()
    rootlogger.setLevel(loglevel)
    configure_logger_for_colour(rootlogger)  # configure root logger
    # -------------------------------------------------------------------------
    # Go
    # -------------------------------------------------------------------------
    log.info("test_mimic_balance")
    log.info("args: {}".format(args))

    mimic = BalanceMimic(args)
    mimic.run()
def main() -> None:
    # -------------------------------------------------------------------------
    # Arguments
    # -------------------------------------------------------------------------
    parser = argparse.ArgumentParser(
        description="test_mimic_rfid_reader -- to test Starfeeder",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--verbose',
                        '-v',
                        action='store_true',
                        help="Be verbose")
    parser.add_argument(
        '--mean_time_between_rfids_s',
        type=float,
        default=1.0,
        help="Mean time between RFID generation (s) when reading")
    add_serial_port_args(parser)
    args = parser.parse_args()
    # -------------------------------------------------------------------------
    # Logging
    # -------------------------------------------------------------------------
    loglevel = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT, level=loglevel)
    rootlogger = logging.getLogger()
    rootlogger.setLevel(loglevel)
    configure_logger_for_colour(rootlogger)  # configure root logger
    # -------------------------------------------------------------------------
    # Go
    # -------------------------------------------------------------------------
    log.info("test_mimic_rfid_reader")
    log.info("args: {}".format(args))

    mimic = RfidMimic(args)
    mimic.run()
def main() -> None:
    logging.basicConfig()
    logging.getLogger("whisker").setLevel(logging.DEBUG)
    configure_logger_for_colour(logging.getLogger())  # configure root logger
    # print_report_on_all_logs()

    parser = argparse.ArgumentParser("Test Whisker raw socket client")
    parser.add_argument('--server', default='localhost',
                        help="Server (default: localhost)")
    parser.add_argument('--port', default=DEFAULT_PORT, type=int,
                        help="Port (default: {})".format(DEFAULT_PORT))
    parser.add_argument(
        '--display_num', default=DEFAULT_DISPLAY_NUM, type=int,
        help="Display number to use (default: {})".format(DEFAULT_DISPLAY_NUM))
    parser.add_argument(
        '--audio_num', default=DEFAULT_AUDIO_NUM, type=int,
        help="Audio device number to use (default: {})".format(
            DEFAULT_AUDIO_NUM))
    parser.add_argument(
        '--input', default=DEFAULT_INPUT_LINE, type=int,
        help="Input line number to use (default: {})".format(
            DEFAULT_INPUT_LINE))
    parser.add_argument(
        '--output', default=DEFAULT_OUTPUT_LINE, type=int,
        help="Output line number to use (default: {})".format(
            DEFAULT_OUTPUT_LINE))
    parser.add_argument(
        '--media_dir', default=DEFAULT_MEDIA_DIR, type=str,
        help="Media directory to use (default: {})".format(
            DEFAULT_MEDIA_DIR))
    parser.add_argument(
        '--bitmap', default=DEFAULT_BITMAP, type=str,
        help="Bitmap to use (default: {})".format(DEFAULT_BITMAP))
    parser.add_argument(
        '--video', default=DEFAULT_VIDEO, type=str,
        help="Video to use (default: {})".format(DEFAULT_VIDEO))
    parser.add_argument(
        '--wav', default=DEFAULT_WAV, type=str,
        help="WAV file to use (default: {})".format(DEFAULT_WAV))
    args = parser.parse_args()

    print("Module run explicitly. Running a Whisker test.")
    w = MyWhiskerTask(
        display_num=args.display_num,
        audio_num=args.audio_num,
        input_line=args.input,
        output_line=args.output,
        media_dir=args.media_dir,
        bitmap=args.bitmap,
        video=args.video,
        wav=args.wav,
    )
    w.connect(args.server, args.port)
    reactor.run()
def main() -> None:
    logging.basicConfig()
    logging.getLogger("whisker").setLevel(logging.DEBUG)
    configure_logger_for_colour(logging.getLogger())  # configure root logger

    parser = argparse.ArgumentParser("Test Whisker raw socket client")
    parser.add_argument('--server', default='localhost',
                        help="Server (default: localhost)")
    parser.add_argument('--port', default=DEFAULT_PORT, type=int,
                        help="Port (default: {})".format(DEFAULT_PORT))
    args = parser.parse_args()

    test_whisker(server=args.server, port=args.port)
예제 #5
0
def main() -> None:
    logging.basicConfig()
    logging.getLogger("whisker").setLevel(logging.DEBUG)
    configure_logger_for_colour(logging.getLogger())  # configure root logger

    parser = argparse.ArgumentParser("Test Whisker raw socket client")
    parser.add_argument('--server',
                        default='localhost',
                        help="Server (default: localhost)")
    parser.add_argument('--port',
                        default=DEFAULT_PORT,
                        type=int,
                        help="Port (default: {})".format(DEFAULT_PORT))
    args = parser.parse_args()

    test_whisker(server=args.server, port=args.port)
예제 #6
0
def main() -> None:
    logging.basicConfig()
    logging.getLogger("whisker").setLevel(logging.DEBUG)
    configure_logger_for_colour(logging.getLogger())  # configure root logger
    # print_report_on_all_logs()

    parser = argparse.ArgumentParser("Test Whisker raw socket client")
    parser.add_argument('--server',
                        default='localhost',
                        help="Server (default: localhost)")
    parser.add_argument('--port',
                        default=DEFAULT_PORT,
                        type=int,
                        help="Port (default: {})".format(DEFAULT_PORT))
    parser.add_argument(
        '--display_num',
        default=DEFAULT_DISPLAY_NUM,
        type=int,
        help="Display number to use (default: {})".format(DEFAULT_DISPLAY_NUM))
    parser.add_argument('--audio_num',
                        default=DEFAULT_AUDIO_NUM,
                        type=int,
                        help="Audio device number to use (default: {})".format(
                            DEFAULT_AUDIO_NUM))
    parser.add_argument('--input',
                        default=DEFAULT_INPUT_LINE,
                        type=int,
                        help="Input line number to use (default: {})".format(
                            DEFAULT_INPUT_LINE))
    parser.add_argument('--output',
                        default=DEFAULT_OUTPUT_LINE,
                        type=int,
                        help="Output line number to use (default: {})".format(
                            DEFAULT_OUTPUT_LINE))
    parser.add_argument(
        '--media_dir',
        default=DEFAULT_MEDIA_DIR,
        type=str,
        help="Media directory to use (default: {})".format(DEFAULT_MEDIA_DIR))
    parser.add_argument(
        '--bitmap',
        default=DEFAULT_BITMAP,
        type=str,
        help="Bitmap to use (default: {})".format(DEFAULT_BITMAP))
    parser.add_argument(
        '--video',
        default=DEFAULT_VIDEO,
        type=str,
        help="Video to use (default: {})".format(DEFAULT_VIDEO))
    parser.add_argument(
        '--wav',
        default=DEFAULT_WAV,
        type=str,
        help="WAV file to use (default: {})".format(DEFAULT_WAV))
    args = parser.parse_args()

    print("Module run explicitly. Running a Whisker test.")
    w = MyWhiskerTask(
        display_num=args.display_num,
        audio_num=args.audio_num,
        input_line=args.input,
        output_line=args.output,
        media_dir=args.media_dir,
        bitmap=args.bitmap,
        video=args.video,
        wav=args.wav,
    )
    w.connect(args.server, args.port)
    reactor.run()
import logging
from attrdict import AttrDict
from datetime import datetime
from twisted.internet import reactor
from whisker.logging import configure_logger_for_colour
from whisker.constants import DEFAULT_PORT
from whisker.convenience import (load_config_or_die,
                                 connect_to_db_using_attrdict,
                                 insert_and_set_id,
                                 ask_user,
                                 save_data)
from whisker.twistedclient import WhiskerTask

log = logging.getLogger(__name__)
configure_logger_for_colour(log)

log.setLevel(logging.DEBUG)  # debug-level logging for this file...
logging.getLogger("whisker").setLevel(logging.DEBUG)  # ... and for Whisker

# =============================================================================
# Constants
# =============================================================================

TASKNAME_SHORT = "countpings"  # no spaces; we'll use it in a filename
TASKNAME_LONG = "Ping Counting Task"

# Our tables. They will be autocreated. (NOTE: do not store separate copies of
# table objects, as they can get out of sync as new columns area created.)
SESSION_TABLE = 'session'
TRIAL_TABLE = 'trial'
# Imports, and configure logging
# =============================================================================

import logging
from attrdict import AttrDict
from datetime import datetime
from twisted.internet import reactor
from whisker.logging import configure_logger_for_colour
from whisker.constants import DEFAULT_PORT
from whisker.convenience import (load_config_or_die,
                                 connect_to_db_using_attrdict,
                                 insert_and_set_id, ask_user, save_data)
from whisker.twistedclient import WhiskerTask

log = logging.getLogger(__name__)
configure_logger_for_colour(log)

log.setLevel(logging.DEBUG)  # debug-level logging for this file...
logging.getLogger("whisker").setLevel(logging.DEBUG)  # ... and for Whisker

# =============================================================================
# Constants
# =============================================================================

TASKNAME_SHORT = "countpings"  # no spaces; we'll use it in a filename
TASKNAME_LONG = "Ping Counting Task"

# Our tables. They will be autocreated. (NOTE: do not store separate copies of
# table objects, as they can get out of sync as new columns area created.)
SESSION_TABLE = 'session'
TRIAL_TABLE = 'trial'
예제 #9
0
def main() -> int:
    # -------------------------------------------------------------------------
    # Arguments
    # -------------------------------------------------------------------------
    parser = argparse.ArgumentParser(
        description="Starfeeder v{}. Whisker bird monitor, reading from RFID "
        "tag readers and weighing balances.".format(VERSION))
    # ... allow_abbrev=False requires Python 3.5
    parser.add_argument("--logfile",
                        default=None,
                        help="Filename to append log to")
    parser.add_argument('--verbose',
                        '-v',
                        action='count',
                        default=0,
                        help="Be verbose (use twice for extra verbosity)")
    parser.add_argument('--guilog',
                        action="store_true",
                        help="Show Python log in a GUI window")
    parser.add_argument('--upgrade-database',
                        action="store_true",
                        help="Upgrade database (determined from SQLAlchemy"
                        " URL, read from {} environment variable) to current"
                        " version".format(DB_URL_ENV_VAR))
    parser.add_argument('--gui',
                        '-g',
                        action="store_true",
                        help="GUI mode only")
    parser.add_argument(
        "--dburl",
        default=None,
        help="Database URL (if not specified, task will look in {} "
        "environment variable).".format(DB_URL_ENV_VAR))
    parser.add_argument('--dbecho',
                        action="store_true",
                        help="Echo SQL to log.")
    parser.add_argument('--debug-qt-signals',
                        action="store_true",
                        help="Debug QT signals.")

    # We could allow extra Qt arguments:
    # args, unparsed_args = parser.parse_known_args()
    # Or not:
    args = parser.parse_args()
    unparsed_args = []

    qt_args = sys.argv[:1] + unparsed_args

    # -------------------------------------------------------------------------
    # Modify settings if we're in a PyInstaller bundle
    # -------------------------------------------------------------------------
    in_bundle = getattr(sys, 'frozen', False)
    if in_bundle:
        args.gui = True
    if not args.gui:
        args.guilog = False

    # -------------------------------------------------------------------------
    # Create QApplication before we create any windows (or Qt will crash)
    # -------------------------------------------------------------------------
    qt_app = QApplication(qt_args)

    # Attempt to fix rare bugs by constraining the Python garbage collector
    # to the GUI thread only

    # noinspection PyUnusedLocal
    my_garbage_collector = GarbageCollector(qt_app, interval_ms=100)
    # ... with interval of 10000, get
    #     pymysql.err.OperationalError (1040, 'Too many connections')
    # ... 500 seems OK
    # ... not sure why there was a problem, though, as all sessions are created
    #     using "with session_thread_scope", and when that finishes, it calls
    #     session.close(), and that's meant to release all resources:
    #     http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#closing
    # ... since I'm not sure, let's use 100 to be conservative

    # -------------------------------------------------------------------------
    # Logging
    # -------------------------------------------------------------------------
    loglevel = logging.DEBUG if args.verbose >= 1 else logging.INFO
    logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT, level=loglevel)
    rootlogger = logging.getLogger()
    rootlogger.setLevel(loglevel)
    configure_logger_for_colour(rootlogger)  # configure root logger
    logging.getLogger('whisker').setLevel(
        logging.DEBUG if args.verbose >= 2 else logging.INFO)
    if args.logfile:
        copy_root_log_to_file(args.logfile)
    if args.guilog:
        log_window = LogWindow(level=loglevel,
                               window_title=WINDOW_TITLE + " Python log",
                               logger=rootlogger)
        log_window.show()

    # If any exceptions happen up to this point, we're a bit stuffed.
    # But from now on, we can trap anything and see it in the GUI log, if
    # enabled, even if we have no console.

    # noinspection PyBroadException
    try:

        # ---------------------------------------------------------------------
        # Info
        # ---------------------------------------------------------------------
        log.info("Starfeeder v{}: RFID/balance controller for Whisker, "
                 "by Rudolf Cardinal ([email protected])".format(VERSION))
        log.debug("args: {}".format(args))
        log.debug("qt_args: {}".format(qt_args))
        log.debug("PyQt5 version: {}".format(PYQT_VERSION_STR))
        log.debug("Qt version: {}".format(QT_VERSION_STR))
        log.debug("Whisker client version: {}".format(whisker.version.VERSION))
        if in_bundle:
            log.debug("Running inside a PyInstaller bundle")
        if args.gui:
            log.debug("Running in GUI-only mode")
        # if args.debug_qt_signals:
        #     enable_signal_debugging_simply()

        # ---------------------------------------------------------------------
        # Database
        # ---------------------------------------------------------------------
        # Get URL, or complain
        if args.dburl:
            set_database_url(args.dburl)
        if args.dbecho:
            set_database_echo(args.dbecho)
        try:
            database_url = get_database_url()
        except ValueError:
            if args.gui:
                win = NoDatabaseSpecifiedWindow()
                if args.guilog:
                    # noinspection PyUnboundLocalVariable
                    win.exit_kill_log.connect(log_window.exit)
                return run_gui(qt_app, win)
            raise ValueError(DATABASE_ENV_VAR_NOT_SPECIFIED)
        engine = create_engine(database_url)
        log.debug("Using database URL: {}".format(engine))  # obscures password

        # Has the user requested a command-line database upgrade?
        if args.upgrade_database:
            sys.exit(
                upgrade_database(ALEMBIC_CONFIG_FILENAME, ALEMBIC_BASE_DIR))
        # Is the database at the correct version?
        (current_revision, head_revision) = get_current_and_head_revision(
            database_url, ALEMBIC_CONFIG_FILENAME, ALEMBIC_BASE_DIR)
        if current_revision != head_revision:
            if args.gui:
                win = WrongDatabaseVersionWindow(current_revision,
                                                 head_revision)
                if args.guilog:
                    # noinspection PyUnboundLocalVariable
                    win.exit_kill_log.connect(log_window.exit)
                return run_gui(qt_app, win)
            raise ValueError(
                WRONG_DATABASE_VERSION_STUB.format(
                    head_revision=head_revision,
                    current_revision=current_revision))

        # ---------------------------------------------------------------------
        # Run app
        # ---------------------------------------------------------------------
        win = BaseWindow()
        if args.guilog:
            # noinspection PyUnboundLocalVariable
            win.exit_kill_log.connect(log_window.exit)
        return run_gui(qt_app, win)

    except:
        if args.guilog:
            log.critical(traceback.format_exc())
            log_window.set_may_close(True)
            return qt_app.exec_()
        else:
            raise