def initialize_site_observations(api, site):
    """Creates an observation at the site for each variable in the PVDAQ
    site's file.

    Parameters
    ----------
    api : io.api.APISession
        API Session object, authenticated for the Reference user.
    site : datamodel.Site
        The site object for which to create the Observations.
    """
    try:
        extra_params = common.decode_extra_parameters(site)
    except ValueError:
        logger.warning('Cannot create reference observations at PVDAQ site '
                       f'{site.name}, missing required parameters.')
        return
    site_api_id = int(extra_params['network_api_id'])
    with open(DEFAULT_SITEFILE) as fp:
        obs_metadata = json.load(fp)['observations']

    for obs in obs_metadata:
        obs_extra_params = json.loads(obs['extra_parameters'])
        if obs_extra_params['network_api_id'] == site_api_id:
            obs['site'] = site
            observation = Observation.from_dict(obs)
            common.check_and_post_observation(api, observation)
 def f(variable):
     return Observation(name='test',
                        variable=variable,
                        interval_value_type='mean',
                        interval_length=pd.Timedelta('1hr'),
                        interval_label='beginning',
                        site=single_site,
                        uncertainty=0.1,
                        observation_id='OBSID',
                        extra_parameters='')
def site_to_obs(site):
    ep = json.loads(site.extra_parameters)
    interval_length = ep['observation_interval_length']
    return Observation.from_dict({
        'name': 'site ghi',
        'variable': 'ghi',
        'interval_label': 'ending',
        'interval_value_type': 'interval_mean',
        'interval_length': interval_length,
        'site': site,
        'uncertainty': 0,
        'extra_parameters': site.extra_parameters
    })
Exemple #4
0
def site_obs():
    return [
        Observation.from_dict({
            'name': 'site ghi',
            'observation_id': str(uuid.uuid1()),
            'variable': 'ghi',
            'interval_label': 'ending',
            'interval_value_type': 'interval_mean',
            'interval_length': '5',
            'site': site,
            'uncertainty': 0,
            'extra_parameters': site.extra_parameters
        }) for site in site_objects[:2]
    ]
Exemple #5
0
def log(mocker):
    log = mocker.patch('solarforecastarbiter.io.reference_observations.'
                       'common.logger')
    return log


site_test_observation = Observation.from_dict({
    'name':
    'site ghi',
    'variable':
    'ghi',
    'interval_label':
    'ending',
    'interval_value_type':
    'interval_mean',
    'interval_length':
    1,
    'site':
    site_objects[0],
    'uncertainty':
    0,
    'extra_parameters': ('{"network": "DOE ARM", '
                         '"observation_interval_length": 1,'
                         '"network_api_id": "api_id", '
                         '"network_api_abbreviation": "siteghi"}')
})
invalid_params = {
    'name': 'site-invalid-jsonparams',
    'latitude': 3,
    'longitude': -3,
    'elevation': 6,
    'timezone': 'Etc/GMT+8',
def create_observation(api, site, variable, extra_params=None, **kwargs):
    """ Creates a new Observation for the variable and site. Kwargs can be
    provided to overwrite the default arguments to the Observation constructor.
    Kwarg options are documented in 'Other Parameters' below but users should
    reference the SolarForecastArbiter API for valid Observation field values.

    Parameters
    ----------
    api : solarforecastarbiter.io.api.APISession
        An APISession with a valid JWT for accessing the Reference Data user.
    site : solarforecastarbiter.datamodel.site
        A site object.
    variable : string
        Variable measured in the observation.
    extra_params : dict, optional
        If provided, this dict will be serialized as the 'extra_parameters'
        field of the observation, otherwise the site's field is copied over.
        Must contain the keys 'network_api_length', 'network_api_id', and
        'observation_interval_length'.

    Other Parameters
    ----------------
    name: string
        Defaults to `<site.name> <variable>`
    interval_label: string
        Defaults to 'ending'
    interval_value_type: string
        Defaults to 'interval_mean'
    uncertainty: float or None
        Defaults to None.

    Returns
    -------
    created
        The datamodel object of the newly created observation.

    Raises
    ------
    KeyError
        When the extra_parameters, either loaded from the site or provided
        by the user is missing 'network_api_abbreviation'
        or 'observation_interval_length'

    """
    # Copy network api data from the site, and get the observation's
    # interval length
    if extra_params:
        extra_parameters = extra_params
    else:
        try:
            extra_parameters = decode_extra_parameters(site)
        except ValueError:
            logger.warning(f'Cannot create observations for site {site.name}'
                           'missing required extra parameters')
            return
    site_name = site_name_no_network(site)
    observation_name = f'{site_name} {variable}'
    # Some site names are too long and exceed the API's limits,
    # in those cases. Use the abbreviated version.
    if len(observation_name) > 64:
        site_abbreviation = extra_parameters["network_api_abbreviation"]
        observation_name = f'{site_abbreviation} {variable}'

    observation = Observation.from_dict({
        'name': kwargs.get('name', observation_name),
        'interval_label': kwargs.get('interval_label', 'ending'),
        'interval_length': extra_parameters['observation_interval_length'],
        'interval_value_type': kwargs.get('interval_value_type',
                                          'interval_mean'),
        'site': site,
        'uncertainty': kwargs.get('uncertainty'),
        'variable': variable,
        'extra_parameters': json.dumps(extra_parameters)
    })

    return check_and_post_observation(api, observation)
Exemple #7
0
def initialize_site_observations(api, site):
    """Creates an observation at the site for each variable in
    an SRML site's file.

    Parameters
    ----------
    api: :py:class:`solarforecastarbiter.io.api.APISession`

    site : :py:class:`solarforecastarbiter.datamodel.Site
        The site object for which to create Observations.

    Notes
    -----
    Since variables are labelled with an integer instrument
    number, Observations are named with their variable and
    instrument number found in the source files.

    e.g. A SRML file contains two columns labelled, 1001, and
    1002. These columns represent GHI at instrument 1 and
    instrument 2 respectively. The `pvlib.iotools` package
    converts these to 'ghi_1' and 'ghi_2' for us. We use these
    labels to differentiate between measurements recorded by
    different instruments.
    """
    # Request ~month old data at initialization to ensure we get a response.
    start = pd.Timestamp.utcnow() - pd.Timedelta('30 days')
    end = start
    try:
        extra_params = common.decode_extra_parameters(site)
    except ValueError:
        logger.warning('Cannot create reference observations at MIDC site '
                       f'{site.name}, missing required parameters.')
        return
    # use site name without network here to build
    # a name with the original column label rather than
    # the SFA variable
    site_name = common.site_name_no_network(site)
    try:
        site_df = fetch(api, site, start, end)
    except error.HTTPError:
        logger.error('Could not find data to create observations '
                     f'for SRML site {site_name}.')
        return
    else:
        if site_df is None:
            logger.error('Could not find data to create observations '
                         f'for SRML site {site_name}.')
            return
        for variable in srml_variable_map.keys():
            matches = [col for col in site_df.columns
                       if col.startswith(variable)]
            for match in matches:
                observation_extra_parameters = extra_params.copy()
                observation_extra_parameters.update({
                    'network_data_label': match})
                try:
                    # Here, we pass a name with match instead of variable
                    # to differentiate between multiple observations of
                    # the same variable
                    common.create_observation(
                        api, site, srml_variable_map[variable],
                        name=f'{site_name} {match}',
                        interval_label='beginning',
                        extra_params=observation_extra_parameters)
                except HTTPError as e:
                    logger.error(
                        f'Failed to create {variable} observation at Site '
                        f'{site.name}. Error: {e.response.text}')
        with open(DEFAULT_SITEFILE) as fp:
            obs_metadata = json.load(fp)['observations']
        for obs in obs_metadata:
            obs_site_extra_params = json.loads(obs['site']['extra_parameters'])
            if obs_site_extra_params['network_api_id'] == extra_params[
                    'network_api_id']:
                obs['site'] = site
                observation = Observation.from_dict(obs)
                common.check_and_post_observation(api, observation)
Exemple #8
0
def log(mocker):
    log = mocker.patch('solarforecastarbiter.io.reference_observations.'
                       'common.logger')
    return log


site_test_observation = Observation.from_dict({
    'name':
    'site ghi',
    'variable':
    'ghi',
    'interval_label':
    'ending',
    'interval_value_type':
    'interval_mean',
    'interval_length':
    1,
    'site':
    site_objects[0],
    'uncertainty':
    0,
    'extra_parameters': ('{"network": "ARM", "observation_interval_length": 1,'
                         '"network_api_id": "api_id", '
                         '"network_api_abbreviation": "siteghi"}')
})
invalid_params = {
    'name': 'site-invalid-jsonparams',
    'latitude': 3,
    'longitude': -3,
    'elevation': 6,
    'timezone': 'Etc/GMT+8',