Skip to content
Snippets Groups Projects
rrd.py 2.49 KiB
"""The data model used for the MetObs widgets using tower data.
"""

import os
from datetime import datetime, timedelta

import rrdtool

from metobscommon.util.calc import altimeter, dewpoint, wind_vector_components
from metobscommon.util.mytime import to_epoch
from aosstower import station


# minimum set of records for the tower
VARS = {'air_temp', 'rh', 'dewpoint',
        'wind_speed', 'winddir_east', 'winddir_north',
        'pressure', 'precip', 'accum_precip',
        'solar_flux', 'altimeter'}


def add_vector_winds(record):
    east, north, spd = wind_vector_components(float(record['wind_speed']),
                                              float(record['wind_dir']))

    record['winddir_east'] = '%.3d' % east
    record['winddir_north'] = '%.3d' % north
    record['wind_speed'] = '%.3d' % spd


def add_altimeter(record, elev=station.ELEVATION):
    record['altimeter'] = '%.3d' % altimeter(float(record['pressure']), elev)


def add_dewpoint(record):
    record['dewpoint'] = '%.3d' % dewpoint(float(record['air_temp']),
                                           float(record['rh']))


def initialize_rrd(filepath, start=None, days=365, data_interval=5):
    """Create a new empty RRD database.
    """
    assert not os.path.exists(filepath), "DB already exists"
    start = start or (datetime.utcnow() - timedelta(days=days))
    # normalize start to data interval
    secs = to_epoch(start)
    secs -= secs % data_interval

    rrdtool.create(filepath,
                   '--start={}'.format(secs),
                   '--step={:d}'.format(data_interval),
                   'DS:air_temp:GAUGE:10:-40:50',
                   'DS:rh:GAUGE:10:0:100',
                   'DS:dewpoint:GAUGE:10:0:100',
                   'DS:wind_speed:GAUGE:10:0:100',
                   'DS:winddir_north:GAUGE:10:-100:100',
                   'DS:winddir_east:GAUGE:10:-100:100',
                   'DS:pressure:GAUGE:10:0:1100',
                   'DS:precip:GAUGE:10:0:100',
                   'DS:accum_precip:GAUGE:10:0:100',
                   'DS:solar_flux:GAUGE:10:0:1000',
                   'DS:altimeter:GAUGE:10:0:100',
                   # native resolution
                   'RRA:AVERAGE:0.5:1:6307200',
                   # 1 minute
                   'RRA:AVERAGE:0.5:{:d}:525600'.format(60/data_interval),
                   # 5 minute
                   'RRA:AVERAGE:0.5:{:d}:105120'.format(300/data_interval),
                   # 30 minute
                   'RRA:AVERAGE:0.5:{:d}:17520'.format(1800/data_interval))