Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/sphinx/source/whatsnew/v0.3.3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Enhancements
* Adds the Erbs model. (:issue:`2`)
* Adds the ``scale_voltage_current_power`` function and ``PVSystem`` method
to support simple array modeling. (:issue:`159`)
* Adds support for ``SingleAxisTracker`` objects in ``ModelChain``.
(:issue:`169`)


Bug fixes
Expand Down
32 changes: 29 additions & 3 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
the time to read the source code for the module.
"""

from functools import partial

import pandas as pd

from pvlib import solarposition, pvsystem, clearsky, atmosphere
from pvlib.tracking import SingleAxisTracker
import pvlib.irradiance # avoid name conflict with full import


Expand Down Expand Up @@ -317,9 +320,32 @@ def run_model(self, times, irradiance=None, weather=None):
airmass_data=self.airmass['airmass_absolute'])
self.irradiance = irradiance

self.total_irrad = self.system.get_irradiance(
self.solar_position['apparent_zenith'],
self.solar_position['azimuth'],
# PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
# have different method signatures, so use partial to handle
# the differences.
if isinstance(self.system, SingleAxisTracker):
self.tracking = self.system.singleaxis(
self.solar_position['apparent_zenith'],
self.solar_position['azimuth'])
self.tracking['surface_tilt'] = (
self.tracking['surface_tilt']
.fillna(self.system.axis_tilt))
self.tracking['surface_azimuth'] = (
self.tracking['surface_azimuth']
.fillna(self.system.axis_azimuth))
get_irradiance = partial(
self.system.get_irradiance,
surface_tilt=self.tracking['surface_tilt'],
surface_azimuth=self.tracking['surface_azimuth'],
solar_zenith=self.solar_position['apparent_zenith'],
solar_azimuth=self.solar_position['azimuth'])
else:
get_irradiance = partial(
self.system.get_irradiance,
self.solar_position['apparent_zenith'],
self.solar_position['azimuth'])

self.total_irrad = get_irradiance(
self.irradiance['dni'],
self.irradiance['ghi'],
self.irradiance['dhi'],
Expand Down
22 changes: 22 additions & 0 deletions pvlib/test/test_modelchain.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import numpy as np
import pandas as pd
from numpy import nan

from pvlib import modelchain, pvsystem
from pvlib.modelchain import ModelChain
from pvlib.pvsystem import PVSystem
from pvlib.tracking import SingleAxisTracker
from pvlib.location import Location

from pandas.util.testing import assert_series_equal, assert_frame_equal
Expand Down Expand Up @@ -100,6 +102,26 @@ def test_run_model_with_weather():
assert_series_equal(ac, expected)


def test_run_model_tracker():
system, location = mc_setup()
system = SingleAxisTracker(module_parameters=system.module_parameters,
inverter_parameters=system.inverter_parameters)
mc = ModelChain(system, location)
times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
ac = mc.run_model(times).ac

expected = pd.Series(np.array([ 121.421719, -2.00000000e-02]),
index=times)
assert_series_equal(ac, expected)

expected = pd.DataFrame(np.
array([[ 54.82513187, 90. , 11.0039221 , 11.0039221 ],
[ nan, 0. , 0. , nan]]),
columns=['aoi', 'surface_azimuth', 'surface_tilt', 'tracker_theta'],
index=times)
assert_frame_equal(mc.tracking, expected)


@raises(ValueError)
def test_bad_get_orientation():
modelchain.get_orientation('bad value')
Expand Down