Beispiel #1
0
def run(printFREQ=60, port=8888):
    '''
	Initialize stream and print constants, then process data for packet loss.

	:param int printFREQ: Value in seconds denoting the frequency with which this program will report packets lost
	:param int port: Local port to listen on

	'''
    global DPtime, DPttlLoss
    printM("Initializing...")
    raspberryshake.initRSlib(
        dport=port, rsstn='Z0000'
    )  # runs in quiet mode; suppresses needless output but shows errors
    add_debug_handler()  # now start console output
    # initialize data stream constants
    printM('Opened data port successfully.')
    DP = raspberryshake.getDATA()
    CHAN = raspberryshake.getCHN(
        DP)  # first channel - doesn't matter which, used to stop looping
    TR = raspberryshake.tf  # transmission rate - in milliseconds
    TRE = (TR +
           TR * .5) / 1000.  # time diff / error to identify a missed packet
    SR = raspberryshake.sps  # sample / second
    ttlCHN = raspberryshake.getTTLCHN()  # total number of channels
    printM("	Total Channels: %s" % ttlCHN)
    printM("	   Sample Rate: %s samples / second" % SR)
    printM("	       TX Rate: Every %s milliseconds" % TR)

    # start processing data packets for packet loss detection
    # initialize
    chnNum = 0
    while chnNum < ttlCHN:
        DP = raspberryshake.getDATA()
        CHAN = raspberryshake.getCHN(DP)
        DPtime[CHAN] = raspberryshake.getTIME(DP)
        timeStart[CHAN] = DPtime[CHAN]
        DPttlLoss[CHAN] = 0
        chnNum += 1

    printM('Data Packet reading begun.')
    printM(
        'Will report any DP loss as it happens and totals every %s seconds.' %
        printFREQ)

    while 1:  # loop forever
        DP = raspberryshake.getDATA()
        CHAN = raspberryshake.getCHN(DP)
        timeS = raspberryshake.getTIME(DP)
        timeD = timeS - DPtime[CHAN]
        if abs(timeD) > TRE:
            printM("DP loss of %s second(s) Current TS: %s, Previous TS: %s" %
                   (round(timeD, 3), timeS, DPtime[CHAN]))
            DPttlLoss[CHAN] += abs(int(timeD * TR))
        DPtime[CHAN] = timeS

        if int(timeS) % printFREQ == 0:
            if printTTLS(CHAN, TR):
                timeStart[CHAN] = timeS
                DPttlLoss[CHAN] = 0
Beispiel #2
0
def test():
    '''
	.. versionadded:: 0.4.3

	Set up tests, run modules, report test results.
	For a list of tests run, see :py:mod:`rsudp.test`.
	'''
    global TESTFILE
    hlp_txt = '''
###########################################
##     R A S P B E R R Y  S H A K E      ##
##            Testing Module             ##
##            by Ian Nesbitt             ##
##            GNU GPLv3 2020             ##
##                                       ##
## Test settings with archived Shake     ##
## data to determine optimal             ##
## configuration.                        ##
##                                       ##
##  Requires:                            ##
##  - numpy, obspy, matplotlib 3         ##
##                                       ##
###########################################

Usage: rs-test [ OPTIONS ]
where OPTIONS := {
    -h | --help
            display this help message
    -f | --file=default or /path/to/data/file
            specify the path to a seismic data file
    -s | --settings=/path/to/settings/json
            specify the path to a JSON-formatted settings file
    -b | --no-plot
            "blind mode", used when there is no display
    -q | --no-sound
            "quiet mode", used when there is no audio device/ffmpeg
    }

rs-test with no arguments will start the test with
default settings and the data file at
%s
''' % (TESTFILE)

    test_mode(True)
    settings = H.default_settings(verbose=False)
    settings_are_default = True
    plot = True
    quiet = False
    customfile = False

    try:
        opts = getopt.getopt(
            sys.argv[1:], 'hf:s:bq',
            ['help', 'file=', 'settings=', 'no-plot', 'no-sound'])[0]
    except Exception as e:
        print(COLOR['red'] + 'ERROR: %s' % e + COLOR['white'])
        print(hlp_txt)
        exit(1)

    for o, a in opts:
        # parse options and arguments
        if o in ('-h', '--help'):
            print(hlp_txt)
            exit(0)
        if o in ('-f', '--file='):
            '''
			The data file.
			'''
            a = os.path.expanduser(a)
            if os.path.exists(a):
                try:
                    out = '%s.txt' % (a)
                    packetize(inf=a, outf=out, testing=True)
                    TESTFILE = out
                    customfile = True  # using a custom miniseed file for testing
                except Exception as e:
                    print(hlp_txt)
                    print(COLOR['red'] + 'ERROR: %s' % e + COLOR['white'])
                    exit(1)
        if o in ('-s', '--settings='):
            '''
			Dump the settings to a file, specified after the `-d` flag, or `-d default` to let the software decide where to put it.
			'''
            settings_loc = os.path.abspath(os.path.expanduser(a)).replace(
                '\\', '/')
            if os.path.exists(settings_loc):
                settings = H.read_settings(settings_loc)
                settings_are_default = False
            else:
                print(COLOR['red'] +
                      'ERROR: could not find settings file at %s' % (a) +
                      COLOR['white'])
                exit(1)
        if o in ('-b', '--no-plot'):
            plot = False
        if o in ('-q', '--no-sound'):
            quiet = True

    if not customfile:
        # we are just using the default miniseed file
        packetize(inf=TESTFILE + '.ms', outf=TESTFILE, testing=True)

    T.TEST['n_internet'][1] = T.is_connected('www.google.com')

    if settings_are_default:
        settings = T.make_test_settings(settings=settings,
                                        inet=T.TEST['n_internet'][1])

    T.TEST['p_log_dir'][1] = T.logdir_permissions()
    T.TEST['p_log_file'][1] = start_logging(testing=True)
    T.TEST['p_log_std'][1] = add_debug_handler(testing=True)

    T.TEST['p_output_dirs'][1] = init_dirs(
        os.path.expanduser(settings['settings']['output_dir']))
    T.TEST['p_data_dir'][1] = T.datadir_permissions(
        os.path.expanduser(settings['settings']['output_dir']))
    T.TEST['p_screenshot_dir'][1] = T.ss_permissions(
        os.path.expanduser(settings['settings']['output_dir']))

    settings = T.cancel_tests(settings, MPL, plot, quiet)

    try:
        run(settings, debug=True)

        # client test
        ctest = 'client test'
        if (T.TEST['c_miniseed'] and WRITER):
            printM('Merging and testing MiniSEED file(s)...', sender=ctest)
            try:
                ms = rs.Stream()
                for outfile in WRITER.outfiles:
                    if os.path.exists(outfile):
                        T.TEST['c_miniseed'][1] = True
                        ms = ms + rs.read(outfile)
                        dn, fn = os.path.dirname(outfile), os.path.basename(
                            outfile)
                        os.replace(outfile, os.path.join(dn, 'test.' + fn))
                    else:
                        raise FileNotFoundError('MiniSEED file not found: %s' %
                                                outfile)
                printM('Renamed test file(s).', sender=ctest)
                printM(ms.merge().__str__())
            except Exception as e:
                printE(e)
                T.TEST['c_miniseed'][1] = False

    except Exception as e:
        printE(traceback.format_exc(), announce=False)
        printE('Ending tests.', sender=SENDER, announce=False)
        time.sleep(0.5)

    TESTQUEUE.put(b'ENDTEST')
    printW('Test finished.', sender=SENDER, announce=False)

    print()

    code = 0
    printM('Test results:')
    for i in T.TEST:
        printM('%s: %s' % (T.TEST[i][0], T.TRANS[T.TEST[i][1]]))
        if not T.TEST[i][1]:
            # if a test fails, change the system exit code to indicate an error occurred
            code = 1
    _xit(code)
Beispiel #3
0
def main():
    '''
	Loads settings to start the main client.
	Supply -h from the command line to see help text.
	'''

    hlp_txt = '''
###########################################
##     R A S P B E R R Y  S H A K E      ##
##              UDP Client               ##
##            by Ian Nesbitt             ##
##            GNU GPLv3 2020             ##
##                                       ##
## Do various tasks with Shake data      ##
## like plot, trigger alerts, and write  ##
## to miniSEED.                          ##
##                                       ##
##  Requires:                            ##
##  - numpy, obspy, matplotlib 3, pydub  ##
##                                       ##
###########################################

Usage: rs-client [ OPTIONS ]
where OPTIONS := {
    -h | --help
            display this help message
    -d | --dump=default or /path/to/settings/json
            dump the default settings to a JSON-formatted file
    -s | --settings=/path/to/settings/json
            specify the path to a JSON-formatted settings file
    }

rs-client with no arguments will start the program with
settings in %s
''' % settings_loc

    settings = json.loads(H.default_settings(verbose=False))

    # get arguments
    try:
        opts = getopt.getopt(sys.argv[1:], 'hid:s:',
                             ['help', 'install', 'dump=', 'settings='])[0]
    except Exception as e:
        print(COLOR['red'] + 'ERROR: %s' % e + COLOR['white'])
        print(hlp_txt)

    if len(opts) == 0:
        if not os.path.exists(settings_loc):
            print(COLOR['yellow'] +
                  'Could not find rsudp settings file, creating one at %s' %
                  settings_loc + COLOR['white'])
            H.dump_default(settings_loc, H.default_settings())
        else:
            settings = H.read_settings(settings_loc)

    for o, a in opts:
        if o in ('-h', '--help'):
            print(hlp_txt)
            exit(0)
        if o in ('-i', '--install'):
            '''
			This is only meant to be used by the install script.
			'''
            os.makedirs(default_loc, exist_ok=True)
            H.dump_default(
                settings_loc,
                H.default_settings(output_dir='@@DIR@@', verbose=False))
            exit(0)
        if o in ('-d', '--dump='):
            '''
			Dump the settings to a file, specified after the `-d` flag, or `-d default` to let the software decide where to put it.
			'''
            if str(a) in 'default':
                os.makedirs(default_loc, exist_ok=True)
                H.dump_default(settings_loc, H.default_settings())
            else:
                H.dump_default(os.path.abspath(os.path.expanduser(a)),
                               H.default_settings())
            exit(0)
        if o in ('-s', 'settings='):
            '''
			Start the program with a specific settings file, for example: `-s settings.json`.
			'''
            settings = H.read_settings(a)

    debug = settings['settings']['debug']
    if debug:
        add_debug_handler()
    start_logging()

    printM('Using settings file: %s' % settings_loc)

    odir = os.path.abspath(
        os.path.expanduser(settings['settings']['output_dir']))
    init_dirs(odir)
    if debug:
        printM('Output directory is: %s' % odir)

    run(settings, debug=debug)
Beispiel #4
0
def main():
    '''
	Loads settings to start the main client.
	Supply -h to see help text.
	'''
    settings_loc = os.path.join(default_loc,
                                'rsudp_settings.json').replace('\\', '/')

    hlp_txt = '''
###########################################
##     R A S P B E R R Y  S H A K E      ##
##           UDP Data Library            ##
##            by Ian Nesbitt             ##
##            GNU GPLv3 2019             ##
##                                       ##
## Do various tasks with Shake data      ##
## like plot, trigger alerts, and write  ##
## to miniSEED.                          ##
##                                       ##
##  Requires:                            ##
##  - numpy, obspy, matplotlib 3, pydub  ##
##                                       ##
###########################################

Usage: rs-client [ OPTIONS ]
where OPTIONS := {
    -h | --help
            display this help message
    -d | --dump=default or /path/to/settings/json
            dump the default settings to a JSON-formatted file
    -s | --settings=/path/to/settings/json
            specify the path to a JSON-formatted settings file
    }

rs-client with no arguments will start the program with
settings in %s
''' % settings_loc

    def default_settings(
            output_dir='%s/rsudp' % os.path.expanduser('~').replace('\\', '/'),
            verbose=True):
        def_settings = r"""{
"settings": {
    "port": 8888,
    "station": "Z0000",
    "output_dir": "%s",
    "debug": true},
"printdata": {
    "enabled": false},
"write": {
    "enabled": false,
    "channels": "all"},
"plot": {
    "enabled": true,
    "duration": 30,
    "spectrogram": true,
    "fullscreen": false,
    "kiosk": false,
    "eq_screenshots": false,
    "channels": ["HZ", "HDF"],
    "deconvolve": false,
    "units": "CHAN"},
"forward": {
    "enabled": false,
    "address": "192.168.1.254",
    "port": 8888,
    "channels": ["all"]},
"alert": {
    "enabled": true,
    "highpass": 0,
    "lowpass": 50,
    "deconvolve": false,
    "units": "VEL",
    "sta": 6,
    "lta": 30,
    "threshold": 1.7,
    "reset": 1.6,
    "exec": "eqAlert",
    "channel": "HZ",
    "win_override": false},
"alertsound": {
    "enabled": false,
    "mp3file": "doorbell"}
}
""" % (output_dir)
        if verbose:
            print('By default output_dir is set to %s' % output_dir)
        return def_settings

    settings = json.loads(default_settings(verbose=False))

    # get arguments
    try:
        opts = getopt.getopt(sys.argv[1:], 'hid:s:',
                             ['help', 'install'
                              'dump=', 'settings='])[0]
    except Exception as e:
        print('ERROR: %s' % e)
        print(hlp_txt)

    if len(opts) == 0:
        if not os.path.exists(settings_loc):
            print('Could not find rsudp settings file, creating one at %s' %
                  settings_loc)
            dump_default(settings_loc, default_settings())
        else:
            with open(os.path.abspath(settings_loc), 'r') as f:
                try:
                    data = f.read().replace('\\', '/')
                    settings = json.loads(data)
                except Exception as e:
                    printM(
                        'ERROR:  Could not load default settings file from %s'
                        % settings_loc)
                    printM('DETAIL: %s' % e)
                    printM(
                        '        Either correct the file, or overwrite the default settings file using the command:'
                    )
                    printM('        shake_client -d default')
                    exit(2)

    for o, a in opts:
        if o in ('-h, --help'):
            print(hlp_txt)
            exit(0)
        if o in ('-i', '--install'):
            '''
			This is only meant to be used by the install script.
			'''
            os.makedirs(default_loc, exist_ok=True)
            dump_default(settings_loc,
                         default_settings(output_dir='@@DIR@@', verbose=False))
            exit(0)
        if o in ('-d', '--dump='):
            '''
			Dump the settings to a file, specified after the `-d` flag, or `-d default` to let the software decide where to put it.
			'''
            if str(a) in 'default':
                os.makedirs(default_loc, exist_ok=True)
                dump_default(settings_loc, default_settings())
            else:
                dump_default(os.path.abspath(os.path.expanduser(a)),
                             default_settings())
            exit(0)
        if o in ('-s', 'settings='):
            '''
			Start the program with a specific settings file, for example: `-s settings.json`.
			'''
            if os.path.exists(os.path.abspath(os.path.expanduser(a))):
                settings_loc = os.path.abspath(os.path.expanduser(a)).replace(
                    '\\', '/')
                with open(settings_loc, 'r') as f:
                    try:
                        data = f.read().replace('\\', '/')
                        settings = json.loads(data)
                    except Exception as e:
                        print(
                            'ERROR:  Could not load settings file. Perhaps the JSON is malformed?'
                        )
                        print('DETAIL: %s' % e)
                        print(
                            '        If you would like to overwrite and rebuild the file, you can enter the command below:'
                        )
                        print('shake_client -d %s' % a)
                        exit(2)
            else:
                print(
                    'ERROR: could not find the settings file you specified. Check the path and try again.'
                )
                print()
                exit(2)

    debug = settings['settings']['debug']
    if debug:
        add_debug_handler()
        printM('Logging initialized successfully.', sender='Main')

    printM('Using settings file: %s' % settings_loc)

    odir = os.path.abspath(
        os.path.expanduser(settings['settings']['output_dir']))
    init_dirs(odir)
    if debug:
        printM('Output directory is: %s' % odir)

    run(settings, debug=debug)
Beispiel #5
0
def main():
    '''
    Loads settings to start the main client.
    Supply -h from the command line to see help text.
    '''
    hlp_txt = '''
###########################################
##     R A S P B E R R Y  S H A K E      ##
##           Archive Forwarder           ##
##            by Ian Nesbitt             ##
##            GNU GPLv3 2021             ##
##                                       ##
## Forward archived Shake data via UDP   ##
## from RS UDP-packet-formatted ASCII    ##
## text to IP/port network locations.    ##
##                                       ##
##  Requires:                            ##
##  - rsudp                              ##
##                                       ##
###########################################

Usage: rsaf -i FILE -d IP.ADR.OF.DST -p PORT
where := {
    -i | --infile
            location of the input text file
    -d | --dest
            destination IP address (four 1-3 digit numbers
            separated by periods; example: 192.168.1.30)
    -p | --port
            destination port (a 1-5 digit number)
    }
'''

    inf, dest, port, phelp = False, False, False, False
    sender = 'main thread'

    try:
        opts = getopt.getopt(sys.argv[1:], 'hi:d:p:',
                             ['help', 'infile=', 'dest=', 'port='])[0]
        for opt, arg in opts:
            if opt in ('-h', '--help'):
                print(hlp_txt)
                phelp = True
            if opt in ('-i', '--infile='):
                inf = arg
            if opt in ('-d', '--dest='):
                dest = arg
            if opt in ('-p', '--port='):
                port = int(arg)

    except Exception as e:
        start_logging(logname='rsaf.log')
        if debug:
            add_debug_handler()
        printE('%s' % e, announce=True, sender=sender)
        print(hlp_txt)
        phelp = True

    if inf and dest and port:
        if debug:
            add_debug_handler()
        start_logging(logname='rsaf.log')

        q = Queue(rs.qsize)
        t = RSAF(q=q, inf=inf, dest=dest, port=port)
        printW('Starting RSAF thread. Press CTRL+C to quit at any time.',
               sender=sender,
               announce=False)
        t.start()
        try:
            while t.alive:
                time.sleep(0.1)
        except KeyboardInterrupt:
            printW('Got interrupt keystroke. Ending transmission.',
                   sender=sender,
                   announce=False)
            q.put(helpers.msg_term())
    else:
        if not phelp:
            print(hlp_txt)