示例#1
0
def birdseye_read(kiwi, downsample_N):
    config = kiwi.get_config(use_cached=True)
    sample_count = kiwi.get_sample_count()
    #if sample_count <= 0:
    #    return None,None
    number_to_read = min(downsample_N, sample_count)
    STRIDE = int(sample_count // number_to_read)
    m = '{:,} in steps of {:,}'.format(number_to_read,
                                       STRIDE) if STRIDE > 1 else 'everything'
    print(' {:,} sample{} in memory.'.format(sample_count,
                                             's' if sample_count > 1 else ''))
    print('Requested {:,} sample{}; will read {}.'.format(
        downsample_N, 's' if downsample_N > 1 else '', m))
    print('First sample taken at {} ({} UTC).'.format(
        ts2dt(config['start'], utc=False), ts2dt(config['start'], utc=True)))
    print('Sampling interval: {:.3f} second'.format(config['interval_ms'] *
                                                    1e-3))

    # - - -

    D = []
    current_page_index = None
    current_page = None
    sample_indices = list(range(0, sample_count, STRIDE))
    addr = [kiwi.sampleindex2flashaddress(i) for i in sample_indices]
    print('Reading', end='', flush=True)
    for sample_index, (page_i, byte_i) in zip(sample_indices, addr):
        #print(sample_index, page_i, byte_i)
        try:
            if 0 == (sample_index // STRIDE) % math.ceil(
                    sample_count // STRIDE / 10):
                print('.', end='', flush=True)

            if current_page_index != page_i:
                logging.debug('Reading logger...')
                begin = page_i * Kiwi.SPI_FLASH_PAGE_SIZE_BYTE
                end = (page_i + 1) * Kiwi.SPI_FLASH_PAGE_SIZE_BYTE - 1
                current_page = kiwi.read_range_core(begin, end)
                if len(current_page) != end - begin + 1:
                    logging.warning(
                        'Invalid response length. Skipping sample {}'.format(
                            sample_index))
                    continue
                current_page_index = page_i
            else:
                logging.debug('reuse')

            d = struct.unpack(
                kiwi.sample_struct_fmt,
                current_page[byte_i:byte_i + kiwi.SAMPLE_SIZE_BYTE])
            D.append([sample_index, *d])

        except KeyboardInterrupt:
            print(' User interrupted.')
            break

    return D, STRIDE
示例#2
0
def read_clock(ent):
    logging.debug('read_clock')
    with Serial(PORT, 115200, timeout=1) as ser:
        kiwi = Kiwi(ser)
        ent.config(state='normal')
        ent.delete(0, tk.END)
        ent.insert(0, '{}'.format(ts2dt(kiwi.read_rtc())))
        ent.config(state='readonly')
示例#3
0
def bin2csv(fn_bin, fn_csv, config):
    logging.debug('Reading and parsing binary file...')
    D = []
    with open(fn_bin, 'rb') as fin:
        while True:
            page = fin.read(Kiwi.SPI_FLASH_PAGE_SIZE_BYTE)
            if len(page) < Kiwi.SPI_FLASH_PAGE_SIZE_BYTE:
                break

            L = list(
                range(
                    0, Kiwi.SPI_FLASH_PAGE_SIZE_BYTE, 4 + 4 + 2 + 2 + 2 + 2 +
                    2 + 2 if config['use_light'] else 4 + 4))
            for a, b in list(zip(L[::], L[1::])):
                d = struct.unpack('ffHHHHHH' if config['use_light'] else 'ff',
                                  page[a:b])
                if any([math.isnan(dd) for dd in d]):
                    break
                D.append(d)

    logging.debug('Reconstructing time axis...')
    if 'logging_start_time' in config and 'logging_interval_code' in config:
        ts = construct_timestamp(
            config['logging_start_time'], len(D),
            SAMPLE_INTERVAL_CODE_MAP[config['logging_interval_code']])
    else:
        ts = construct_timestamp(config['start'], len(D),
                                 config['interval_ms'] * 1e-3)
    dt = [ts2dt(tmp) for tmp in ts]
    tmp = list(zip(*D))
    tmp.insert(0, ts)
    tmp.insert(0, dt)
    D = zip(*tmp)

    logging.debug('Writing to {}...'.format(fn_csv))
    with open(fn_csv, 'w', newline='') as fout:
        writer = csv.writer(fout, delimiter=',')
        if config['use_light']:
            fs = [
                str, str, lambda x: '{:.4f}'.format(x),
                lambda x: '{:.3f}'.format(x), str, str, str, str, str, str
            ]
            writer.writerow([
                'UTC_datetime', 'posix_timestamp', 'T_DegC', 'P_kPa',
                'ambient_light_hdr', 'white_light_hdr', 'red', 'green', 'blue',
                'white'
            ])
        else:
            fs = [
                str, str, lambda x: '{:.4f}'.format(x),
                lambda x: '{:.3f}'.format(x)
            ]
            writer.writerow(
                ['UTC_datetime', 'posix_timestamp', 'T_DegC', 'P_kPa'])
        for d in D:
            #writer.writerow([str(x) for x in d])
            writer.writerow([f(x) for f, x in zip(fs, d)])
示例#4
0
                    good = False
                    break
                D.append(d)

        except KeyboardInterrupt:
            break

    # reconstruct time axis using logging start time and sample interval
    print('Reading config {}'.format(configfilename))
    config = json.loads(open(configfilename).read())
    logging_start_time = config['logging_start_time']
    logging_stop_time = config.get('logging_stop_time', None)

    if logging_stop_time is not None and logging_stop_time > logging_start_time:
        print('{} samples from {} to {} spanning {}'.format(
            len(D), ts2dt(logging_start_time), ts2dt(logging_stop_time),
            ts2dt(logging_stop_time) - ts2dt(logging_start_time)))
        print(
            'Effective sample rate {:.3f} sample/second or an average interval of {:.3f} second'
            .format(
                len(D) / (logging_stop_time - logging_start_time),
                (logging_stop_time - logging_start_time) / len(D)))
    else:
        logging.warning(
            'No record of logging_stop_time. Are the batteries good? Did someone remove power without stopping logging first?'
        )

    logging_interval_code = config['logging_interval_code']

    print('Reconstructing time axis...')
    ts = np.linspace(0, len(D) - 1, num=len(D))
示例#5
0
    logging.basicConfig(level=logging.WARNING)

    #fn = UNIQUE_ID + '.csv'
    #fn = input('Path to the CSV file: ').strip()

    d = find('data/*', dironly=True)
    fn = find(join(d, '*.csv'), fileonly=True, default='last')
    if fn is None:
        print('No CSV file found. Have you run bin2csv.py? Terminating.')
        sys.exit()

    logger_name = get_logger_name(fn)

    ts, t, p, als, white, r, g, b, w = read_and_parse_data(fn)
    begin, end = ts2dt(min(ts)), ts2dt(max(ts))

    if len(ts) <= 1:
        print('Only less than two measurements are available. ABORT.')

    print(
        '{} samples from {} to {} spanning {}, average interval {:.3}s'.format(
            len(ts), begin, end, end - begin, ts[1] - ts[0]))

    # - - -

    #print(describe(p))

    # also PSD... TODO
    '''print('Calculating Temperature statistics...')
    plt.figure(figsize=(16, 9))
示例#6
0
def birdseye_plot(D, STRIDE, config, sample_count, use_utc):
    D = list(zip(*D))
    D[0] = [
        ts2dt(i * config['interval_ms'] * 1e-3 + config['start'], utc=use_utc)
        for i in D[0]
    ]

    print(' plotting... ', end='', flush=True)

    fig, ax = plt.subplots(4 if config['use_light'] else 2,
                           1,
                           figsize=(16, 9),
                           sharex=True)
    for tmp in ax[:-1]:
        plt.setp(tmp.get_xticklabels(), visible=False)
    ax[-1].set_xlabel('UTC Time' if use_utc else 'Local Time')

    if STRIDE > 1:
        ax[0].set_title(
            'Memory Overview (plotting one out of every {:,})'.format(
                STRIDE, sample_count))
    else:
        ax[0].set_title('Memory Overview (plotting everything)')

    # add caption
    span = max(D[0]) - min(D[0])
    if span > timedelta(days=2):
        span = '{:.1f} days'.format(span.total_seconds() / 3600 / 24)
    else:
        span = '{:.1f} hours'.format(span.total_seconds() / 3600)

    s = 'Logger "{}" (ID={})'.format(config['name'], config['id'])
    s += '\n{:,} samples from {} to {} spanning ~{}'.format(
        sample_count,
        min(D[0]).isoformat()[:19].replace('T', ' '),
        max(D[0]).isoformat()[:19].replace('T', ' '),
        span,
    )
    s += '\nSample interval={:.3f} second{}'.format(
        config['interval_ms'] * 1e-3,
        's' if config['interval_ms'] > 1000 else '')

    if STRIDE > 1:
        s += '\n{:,} out of {:,} samples plotted (in steps of {:,})'.format(
            len(D[0]), sample_count, STRIDE)
    else:
        s += '\nAll samples plotted'

    plt.figtext(0.99,
                0.01,
                s,
                horizontalalignment='right',
                color='k',
                alpha=0.5)

    ax[0].plot_date(D[0], D[1], 'r.:', label='℃')
    ax[0].legend(loc=2)
    ax[0].grid(True)

    ax[1].plot_date(D[0], D[2], '.:', label='kPa')
    ax[1].legend(loc=2)
    ax[1].grid(True)

    if config['use_light']:
        ax[2].plot_date(D[0], D[3], '.:', label='HDR_ALS', alpha=0.5)
        ax[2].plot_date(D[0], D[4], '.:', label='HDR_W', alpha=0.5)
        ax[2].legend(loc=2)
        ax[2].grid(True)

        ax[3].plot_date(D[0], D[5], 'r.:', label='R', alpha=0.5)
        ax[3].plot_date(D[0], D[6], 'g.:', label='G', alpha=0.5)
        ax[3].plot_date(D[0], D[7], 'b.:', label='B', alpha=0.5)
        ax[3].plot_date(D[0], D[8], 'k.:', label='W', alpha=0.2)
        ax[3].legend(loc=2)
        ax[3].grid(True)

    ax[-1].xaxis.set_major_formatter(DateFormatter('%b %d %H:%M:%S'))
    plt.tight_layout()
    plt.gcf().autofmt_xdate()

    #print('Saving plot to disk...')
    #plt.savefig(fn.split('.')[0] + '.png', dpi=300)
    print('voila!')
    plt.show()
示例#7
0
        assert not kiwi.is_logging()

        # Turn off LEDs
        ser.write(b'red_led_off green_led_off blue_led_off' if 0 == kiwi._version else b'roffgoffboff')

        if 0 == kiwi._version:
            # Set RTC to current UTC time
            print('Synchronizing clock to UTC...', flush=True)
            for i in range(MAX_RETRY):
                device_time = kiwi.set_rtc_aligned()
                if abs(device_time - time.time()) <= 2:
                    break
            else:
                print('Cannot set logger clock. Terminating.')
                sys.exit()
            print('Logger time: {} ({} UTC)'.format(ts2dt(device_time, utc=False), ts2dt(device_time, utc=True)))

        if 0 == kiwi._version:
            use_light_sensors = True
        else:
            while True:
                r = input('Use light sensors? (yes/no; default=yes)').strip().lower()
                if r in ['', 'yes', 'no']:
                    use_light_sensors = r not in ['no']
                    break

            for i in range(MAX_RETRY):
                ser.write(b'enable_light_sensors' if use_light_sensors else b'disable_light_sensors')
                if 'OK' == ser.readline().strip():
                    break