Skip to content

Commit

Permalink
Merge pull request #12 from aaghamohammadi/dev
Browse files Browse the repository at this point in the history
Ready to publish v1.5.0
  • Loading branch information
aaghamohammadi authored Dec 20, 2023
2 parents 23b68d4 + 38627b8 commit 1edc715
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 44 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pysolorie

[![CodeQL](https://github.com/aaghamohammadi/pysolorie/actions/workflows/github-code-scanning/codeql/badge.svg?branch=main)](https://github.com/aaghamohammadi/pysolorie/actions/workflows/github-code-scanning/codeql)
[![Quality Checks](https://github.com/aaghamohammadi/pysolorie/actions/workflows/quality_checks.yml/badge.svg?branch=main)](https://github.com/aaghamohammadi/pysolorie/actions/workflows/quality_checks.yml)
[![Publish](https://github.com/aaghamohammadi/pysolorie/actions/workflows/publish.yml/badge.svg?branch=main)](https://github.com/aaghamohammadi/pysolorie/actions/workflows/publish.yml)
![GitHub License](https://img.shields.io/github/license/aaghamohammadi/pysolorie)
Expand All @@ -9,6 +10,9 @@
![PyPI - Format](https://img.shields.io/pypi/format/pysolorie)
![PyPI - Status](https://img.shields.io/pypi/status/pysolorie)
[![codecov](https://codecov.io/gh/aaghamohammadi/pysolorie/graph/badge.svg?token=TF9E8Y3Q67)](https://codecov.io/gh/aaghamohammadi/pysolorie)
![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)
![code style: black](https://img.shields.io/badge/code%20style-black-black)


**pysolorie** stands for **Py**thon **Sol**ar **Orie**ntation Analysis of Solar Panel. It is a Python library designed to help you analyze the orientation of solar panels.

Expand All @@ -21,14 +25,15 @@ How can one maximize the solar irradiation energy received by a solar panel?

``pysolorie`` is a library designed to help you find this optimal orientation. Its features include, but are not limited to:

- Finding the optimal orientation for a fixed solar panel under the assumption of a clear-sky model.
- Plotting the Optimal Orientation for a range of days.
- Generating a CSV Report of the optimal orientation for a range of days.
- Calculating the sunrise and sunset hour angles for a given day.
- Utilizing the Hottel's Model to estimate clear-sky beam radiation transmittance.
- Finding the optimal orientation for a fixed solar panel, assuming a clear-sky model.
- Plotting the optimal orientation over a range of days.
- Plotting the total direct irradiation over a range of days.
- Generating a CSV report detailing the optimal orientation over a range of days.
- Calculating the sunrise and sunset hour angles for a specific day.
- Utilizing Hottel’s Model to estimate the transmittance of clear-sky beam radiation.
- Calculating the solar zenith angle.
- Calculating the solar time.
- Calculating Solar Declination and Hour Angle.
- Calculating solar declination and hour angle.



Expand Down
35 changes: 35 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
Changelog
=========

Version 1.5.0
-------------

Release date: 2023-12-20

Added
^^^^^
- Added badges for CodeQL, pre-commit, and code style (black) in README.md, enhancing the visibility of code quality and style adherence.
- Implemented ``generate_optimal_orientation_json_report`` method for JSON report generation in ``ReportGenerator``.
- Developed ``generate_optimal_orientation_xml_report`` method in ``ReportGenerator`` for producing XML formatted reports.
- Expanded ``test_pysolorie.py`` with tests for JSON (``test_generate_optimal_orientation_json_report``) and XML (``test_generate_optimal_orientation_xml_report``) report generation.

Changed
^^^^^^^
- Updated ``plot_total_direct_irradiation`` method's ``ylabel`` argument to use "Megajoules per square meter" instead of "MW/m²" for clarity and accuracy in ``plotter.py``.
- Refactored ``plot_total_direct_irradiation`` in ``Plotter`` to use a private method for calculating optimal orientations, streamlining the plotting process.

Fixed
^^^^^
- Altered the ``Plotter`` methods to handle axis labels and titles through dynamic ``plot_kwargs``, making the labeling more robust and customizable.
- Harmonized and corrected unit values and labelings across the entire codebase and documentation for consistency and accuracy.
- Refined the ``ReportGenerator`` generate methods' docstrings, clearly specifying the return value unit as "Megajoules per square meter".
- Changed the calculation of the solar irradiance formula in ``SolarIrradiance`` from ``0.33`` to ``0.033`` to correct the eccentricity correction factor according to established astronomical equations.


Documentation
^^^^^^^^^^^^^
- Enhanced documentation in ``getting_started.rst`` with examples and instructions for the new JSON and XML report generation methods.
- Altered the representation of solar irradiance units in documentation to match the codebase changes.

Testing
^^^^^^^
- Enriched ``test_pysolorie.py`` with further assertions for newly added JSON and XML report functionalities, ensuring correct report file creation and data integrity.



Version 1.4.0
-------------
Expand Down
49 changes: 46 additions & 3 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,49 @@ the optimal orientation for a range of days.
The CSV file will be saved to the specified path.

Generating a JSON Report
------------------------

The ``generate_optimal_orientation_json_report`` method generates a JSON report of
the optimal orientation for a range of days.

.. code-block:: python
from pysolorie import ReportGenerator, IrradiationCalculator
from pathlib import Path
# Create a report generator and an irradiation calculator
report_generator = ReportGenerator()
irradiation_calculator = IrradiationCalculator("MIDLATITUDE SUMMER", 1200, 35.6892)
# Generate a JSON report for days 60 to 70
report_generator.generate_optimal_orientation_json_report(Path('results.json'), irradiation_calculator, 60, 70)
The JSON file will be saved to the specified path.


Generating an XML Report
------------------------

The ``generate_optimal_orientation_xml_report`` method generates an XML report of
the optimal orientation for a range of days.

.. code-block:: python
from pysolorie import ReportGenerator, IrradiationCalculator
from pathlib import Path
# Create a report generator and an irradiation calculator
report_generator = ReportGenerator()
irradiation_calculator = IrradiationCalculator("MIDLATITUDE SUMMER", 1200, 35.6892)
# Generate an XML report for days 60 to 70
report_generator.generate_optimal_orientation_xml_report(Path('results.xml'), irradiation_calculator, 60, 70)
The XML file will be saved to the specified path.




Plotting the Optimal Orientation
--------------------------------
Expand Down Expand Up @@ -129,7 +172,7 @@ The ``plot_total_direct_irradiation`` method plots the total direct irradiation
irradiation_calculator = IrradiationCalculator("MIDLATITUDE SUMMER", 1200, 35.6892)
# Plot the total direct irradiation for days 60 to 70
plotter.plot_total_direct_irradiation(irradiation_calculator, 60, 70, Path('results.png'), plot_kwargs={'xlabel': 'Day', 'ylabel': 'Total Direct Irradiation (MW/m²)', 'title': 'Total Direct Irradiation', "figsize": (16,9)}, savefig_kwargs={'dpi': 300})
plotter.plot_total_direct_irradiation(irradiation_calculator, 60, 70, Path('results.png'), plot_kwargs={'xlabel': 'Day', 'ylabel': 'Total Direct Irradiation (Megajoules per square meter)', 'title': 'Total Direct Irradiation', "figsize": (16,9)}, savefig_kwargs={'dpi': 300})
The plot will be saved to the specified path. The ``plot_kwargs`` and ``savefig_kwargs``
parameters can be used to customize the plot and the savefig function, respectively. If no path is provided, the plot will be displayed but not saved.
Expand Down Expand Up @@ -158,8 +201,8 @@ for a given day of the year.
print(f"Sunset hour angle: {sunset_hour_angle}")
Calculating the Zenith Angle
----------------------------
Calculating the Solar Zenith Angle
----------------------------------

The ``calculate_zenith_angle`` method calculates the zenith angle given the day of the year
and solar time.
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pysolorie
version = 1.4.0
version = 1.5.0
description = Orientation Analysis of Solar Panel
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
2 changes: 1 addition & 1 deletion src/pysolorie/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def calculate_extraterrestrial_irradiance(self, day_of_year: int) -> float:
.. math::
I = SC
\times (1 + 0.33 \times \cos (\frac{2\pi~n}{365}))
\times (1 + 0.033 \times \cos (\frac{2\pi~n}{365}))
| - :math:`SC` is the average solar radiation arriving outside
Expand Down
2 changes: 1 addition & 1 deletion src/pysolorie/numerical_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def calculate_direct_irradiation(
:type panel_orientation: float
:param day_of_year: The day of the year.
:type day_of_year: int
:return: The total direct irradiation.
:return: The total direct irradiation in Megajoules per square meter.
:rtype: float
"""
sunrise_hour_angle, sunset_hour_angle = self._observer.calculate_sunrise_sunset(
Expand Down
23 changes: 10 additions & 13 deletions src/pysolorie/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,13 @@ def plot_total_direct_irradiation(
:type savefig_kwargs: dict, optional
"""

days = []
total_direct_irradiations = []

for day in range(from_day, to_day):
optimal_beta = irradiation_calculator.find_optimal_orientation(day)
total_direct_irradiation = (
irradiation_calculator.calculate_direct_irradiation(optimal_beta, day)
)
days.append(day)
total_direct_irradiations.append(total_direct_irradiation)
days, betas = self._calculate_optimal_orientations(
irradiation_calculator, from_day, to_day
)
total_direct_irradiations = [
irradiation_calculator.calculate_direct_irradiation(beta, day)
for day, beta in zip(days, betas)
]

plot_kwargs = plot_kwargs if plot_kwargs else {}
savefig_kwargs = savefig_kwargs if savefig_kwargs else {}
Expand Down Expand Up @@ -141,9 +138,9 @@ def _plot(
figsize = plot_kwargs.get("figsize", (10, 6))
fig, ax = plt.subplots(figsize=figsize)
ax.plot(days, betas)
ax.set_xlabel(plot_kwargs.get("xlabel", "Day"))
ax.set_ylabel(plot_kwargs.get("ylabel", "Beta (degrees)"))
ax.set_title(plot_kwargs.get("title", "Optimal Solar Panel Orientation"))
ax.set_xlabel(plot_kwargs.get("xlabel", "X Axis Title"))
ax.set_ylabel(plot_kwargs.get("ylabel", "Y Axis Title"))
ax.set_title(plot_kwargs.get("title", "Title"))
ax.grid(True)

if path is not None:
Expand Down
Loading

0 comments on commit 1edc715

Please sign in to comment.