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: 1 addition & 1 deletion .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push]

jobs:
flake8:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.7
- uses: actions/setup-python@v5.1.0
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Static Code Analysis

on: [push]

jobs:
mypy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Pip Dependencies
run: pip install -r requirements.txt

- name: Run MyPy
run: mypy solar_angles --disallow-untyped-calls --disallow-untyped-defs --check-untyped-defs
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ defaults:

jobs:
release:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.7
- uses: actions/setup-python@v5.1.0
with:
python-version: 3.12
- run: pip install wheel setuptools
- run: python3 setup.py bdist_wheel sdist
- uses: pypa/gh-action-pypi-publish@v1.9.0
- uses: pypa/gh-action-pypi-publish@v1.13.0
with:
user: __token__
password: ${{ secrets.PYPIPW }}
7 changes: 3 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,20 @@ jobs:
unit_testing:
strategy:
matrix:
os: [ windows-latest, macos-12, ubuntu-24.04 ]
py: [ "3.11", "3.12" ]
os: [ windows-latest, macos-latest, ubuntu-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4.1.7
- name: Set up Python
uses: actions/setup-python@v5.1.0
with:
python-version: ${{ matrix.py }}
python-version: 3.14
- name: Install Pip Dependencies from Requirements
run: pip install -r requirements.txt
- name: Run Tests
run: coverage run -m pytest && coverage report -m
- name: Coveralls
if: ${{ matrix.os == 'ubuntu-24.04' }}
if: ${{ matrix.os == 'ubuntu-latest' }}
run: coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is a collection of solar angle and related calculations.
## Source
These are based mostly on Chapter 6 of _Heating, Ventilation, and Air Conditioning_ by Faye McQuistion and Jerald Parker, 3rd Edition, 1988, with minor pieces from other versions of the same book. Other sources are noted in the source. All the functions were written from scratch by me.

## Releases [![PyPIRelease](https://github.com/Myoldmopar/SolarCalculations/actions/workflows/release.yml/badge.svg)](https://github.com/Myoldmopar/SolarCalculations/actions/workflows/release.yml) ![PyPI - Version](https://img.shields.io/pypi/v/solar-angles?color=44cc11)
## Releases [![PyPIRelease](https://github.com/Myoldmopar/SolarCalculations/actions/workflows/release.yml/badge.svg)](https://github.com/Myoldmopar/SolarCalculations/actions/workflows/release.yml) x
The latest release can be found on the [Releases](https://github.com/Myoldmopar/SolarCalculations/releases/latest) page. All packages are distributed through [PyPi](https://pypi.org/project/solar-angles/).

## Documentation [![Documentation Status](https://readthedocs.org/projects/solarcalculations/badge/?version=latest)](https://solarcalculations.readthedocs.io/en/latest/?badge=latest)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pytest
coverage
coveralls
flake8
mypy

# for documentation
sphinx
Expand Down
2 changes: 1 addition & 1 deletion solar_angles/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
PACKAGE_NAME = "solar_angles"
VERSION = "0.26"
VERSION = "0.30"
26 changes: 14 additions & 12 deletions solar_angles/demos/compare_to_eplus.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
from datetime import datetime
import csv

from solar_angles.solar import hour_angle, altitude_angle, azimuth_angle, solar_angle_of_incidence
from solar_angles.solar import hour_angle, altitude_angle, azimuth_angle, solar_angle_of_incidence, Angular

# Golden, CO
longitude = 104.85
standard_meridian = 105
latitude = 39.57
longitude = Angular(degrees=104.85)
standard_meridian = Angular(degrees=105)
latitude = Angular(degrees=39.57)

with open('/tmp/compare_winter_angles_library.csv', 'w') as csvfile:
my_writer = csv.writer(csvfile)
my_writer.writerow(['Hour', 'Hour Angle', 'Solar Altitude', 'Solar Azimuth'])
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
x = hour
dt = datetime(2001, 12, 21, hour, 30, 00)
t_hour = hour_angle(dt, False, longitude, standard_meridian).degrees
altitude = altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees
azimuth = azimuth_angle(dt, False, longitude, standard_meridian, latitude).degrees
t_hour = hour_angle(dt, False, longitude, standard_meridian).degrees()
altitude = altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees()
azimuth = azimuth_angle(dt, False, longitude, standard_meridian, latitude).degrees()
my_writer.writerow([x, -t_hour, altitude, azimuth])

with open('/tmp/compare_summer_angles_library.csv', 'w') as csvfile:
Expand All @@ -25,19 +25,21 @@
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
x = hour
dt = datetime(2001, 7, 21, hour, 30, 00)
t_hour = hour_angle(dt, False, longitude, standard_meridian).degrees
altitude = altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees
azimuth = azimuth_angle(dt, False, longitude, standard_meridian, latitude).degrees
t_hour = hour_angle(dt, False, longitude, standard_meridian).degrees()
altitude = altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees()
azimuth = azimuth_angle(dt, False, longitude, standard_meridian, latitude).degrees()
my_writer.writerow([x, -t_hour, altitude, azimuth])

with open('/tmp/compare_summer_incidence_library.csv', 'w') as csvfile:
my_writer = csv.writer(csvfile)
my_writer.writerow(['Hour', 'East Incidence', 'West Incidence'])
az_west = Angular(degrees=270)
az_east = Angular(degrees=90)
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
x = hour
dt = datetime(2001, 7, 21, hour, 30, 00)
theta_west = solar_angle_of_incidence(
dt, False, longitude, standard_meridian, latitude, 270).degrees
dt, False, longitude, standard_meridian, latitude, az_west)
theta_east = solar_angle_of_incidence(
dt, False, longitude, standard_meridian, latitude, 90).degrees
dt, False, longitude, standard_meridian, latitude, az_east)
my_writer.writerow([x, theta_east, theta_west])
67 changes: 36 additions & 31 deletions solar_angles/demos/daylight_hours.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
# import the datetime library so we construct proper datetime instances
from datetime import datetime
from math import nan

# import the plotting library for demonstration -- pip install matplotlib should suffice
import matplotlib.pyplot as plt

# import the solar_angles library
from solar_angles.solar import altitude_angle
from solar_angles.solar import altitude_angle, Angular


def calculate_sun_up_time(array_of_altitude_angles):
def calculate_sun_up_time(array_of_altitude_angles: list[Angular]) -> float:
found_above_time = False
last_alpha = None
for index, alpha in enumerate(array_of_altitude_angles):
last_alpha = -nan
for index, alpha_angle in enumerate(array_of_altitude_angles):
alpha = alpha_angle.degrees()
if not found_above_time and alpha > 0:
# we've got a match, calculate sun up and return
sun_up_time = (index - 1) - (last_alpha / alpha) / (alpha - last_alpha)
return sun_up_time
else:
last_alpha = alpha
return 0.0


def calculate_sun_down_time(array_of_altitude_angles):
def calculate_sun_down_time(array_of_altitude_angles: list[Angular]) -> float:
found_below_time = False
last_alpha = None
for index, alpha in enumerate(array_of_altitude_angles):
last_alpha = -nan
for index, alpha_angle in enumerate(array_of_altitude_angles):
alpha = alpha_angle.degrees()
if index < 12:
continue
if not found_below_time and alpha < 0:
Expand All @@ -32,58 +36,59 @@ def calculate_sun_down_time(array_of_altitude_angles):
return sun_down_time
else:
last_alpha = alpha
return 0.0


# calculate times in Stillwater, OK -- to demonstrate the effect of longitude not lining up with the std meridian
longitude = 97.05
standard_meridian = 90
latitude = 36.11
longitude = Angular(degrees=97.05)
standard_meridian = Angular(degrees=90)
latitude = Angular(degrees=36.11)
x = []
for hour in range(0, 24):
x.append(hour)

alpha0721 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 7, 21, hour, 00, 00)
alpha0721.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha0721.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha0821 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 8, 21, hour, 00, 00)
alpha0821.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha0821.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha0921 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 9, 21, hour, 00, 00)
alpha0921.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha0921.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha1021 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 10, 21, hour, 00, 00)
alpha1021.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha1021.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha1121 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 11, 21, hour, 00, 00)
alpha1121.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha1121.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha1207 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 12, 7, hour, 00, 00)
alpha1207.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha1207.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha1221 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 12, 21, hour, 00, 00)
alpha1221.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)

plt.plot(x, alpha0721, 'purple', label='7/21', linewidth=1)
plt.plot(x, alpha0821, 'blue', label='8/21', linewidth=1)
plt.plot(x, alpha0921, 'green', label='9/21', linewidth=1)
plt.plot(x, alpha1021, 'yellow', label='10/21', linewidth=1)
plt.plot(x, alpha1121, 'orange', label='11/21', linewidth=1)
plt.plot(x, alpha1207, 'red', label='12/7', linewidth=1)
plt.plot(x, alpha1221, 'black', label='12/21', linewidth=1)
alpha1221.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

plt.plot(x, [x.degrees() for x in alpha0721], 'purple', label='7/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha0821], 'blue', label='8/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha0921], 'green', label='9/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1021], 'yellow', label='10/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1121], 'orange', label='11/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1207], 'red', label='12/7', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1221], 'black', label='12/21', linewidth=1)
plt.xlim([0, 23])
plt.ylim([0, 90])
plt.suptitle("Time Values for Stillwater", fontsize=14, fontweight='bold')
Expand All @@ -97,21 +102,21 @@ def calculate_sun_down_time(array_of_altitude_angles):
alpha1207 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 12, 7, hour, 00, 00)
alpha1207.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha1207.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha1221 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 12, 21, hour, 00, 00)
alpha1221.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha1221.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

alpha0107 = []
for hour in range(0, 24): # gives zero-based hours as expected in the datetime constructor
dt = datetime(2001, 1, 7, hour, 00, 00)
alpha0107.append(altitude_angle(dt, False, longitude, standard_meridian, latitude).degrees)
alpha0107.append(altitude_angle(dt, False, longitude, standard_meridian, latitude))

plt.plot(x, alpha1207, 'orange', label='12/7', linewidth=1)
plt.plot(x, alpha1221, 'black', label='12/21', linewidth=1)
plt.plot(x, alpha0107, 'red', label='1/7', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1207], 'orange', label='12/7', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha1221], 'black', label='12/21', linewidth=1)
plt.plot(x, [x.degrees() for x in alpha0107], 'red', label='1/7', linewidth=1)
plt.xlim([7, 18])
plt.ylim([0, 35])
plt.suptitle("Time Values for Stillwater", fontsize=14, fontweight='bold')
Expand Down
Loading