Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jkittner committed Oct 6, 2023
1 parent 7f1149a commit b8451ff
Show file tree
Hide file tree
Showing 17 changed files with 1,773 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
BasedOnStyle: Google
AlwaysBreakAfterReturnType: All
AllowShortIfStatementsOnASingleLine: false
AlignAfterOpenBracket: Align
BreakBeforeBraces: Stroustrup
ColumnLimit: 88
DerivePointerAlignment: false
IndentWidth: 4
PointerAlignment: Right
ReflowComments: true
SpaceBeforeParens: ControlStatements
SpacesInParentheses: false
SortIncludes: false
UseTab: Never
27 changes: 27 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: ci

on:
pull_request:
push:
branches: [main]

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
pg-version: [10, 11, 12, 13, 14, 15]
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: install dependencies
run: pip install -r requirements-dev
- name: run tests
run: |
coverage run -m pytest
coverage report
env:
PG_VERSION: ${{ matrix.pg-version }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.pyc
*venv
.coverage
.pytest_cache
.vscode
58 changes: 58 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
ci:
autoupdate_schedule: monthly
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-docstring-first
- id: check-json
- id: check-yaml
- id: name-tests-test
- id: debug-statements
- id: check-added-large-files
- id: requirements-txt-fixer
- id: double-quote-string-fixer
- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
additional_dependencies: [flake8-typing-imports==1.14.0]
args: [--min-python-version=3.8]
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.4
hooks:
- id: autopep8
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.12.0
hooks:
- id: reorder-python-imports
args: [--py3-plus]
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma
args: [--py36-plus]
- repo: https://github.com/theendlessriver13/double-indent
rev: 0.1.4
hooks:
- id: double-indent
- repo: https://github.com/asottile/pyupgrade
rev: v3.14.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.5.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
- id: mypy
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 'v16.0.6'
hooks:
- id: clang-format
exclude: ^solpos(00)?.(c|h)
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ARG VERSION
FROM postgres:${VERSION}-bullseye

ARG VERSION

RUN : \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential \
gcc \
postgresql-server-dev-$VERSION \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /usr/local/lib/funcs

COPY ./pg_solpos.c .
COPY ./solpos* .

RUN : \
&& cc -fPIC -Werror -c solpos.c \
&& cc -fPIC -Werror -c pg_solpos.c -lm -I /usr/include/postgresql/${VERSION}/server \
&& cc -shared -o pg_solpos.so pg_solpos.o solpos.o \
&& find . -name "*solpos*" | grep -v pg_solpos.so | xargs rm
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Jonas Kittner

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[![ci](https://github.com/jkittner/solpos-postgres/actions/workflows/CI.yaml/badge.svg)](https://github.com/jkittner//asolpos-postgresctions/workflows/CI.yml)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/jkittner/solpos-postgres/main.svg)](https://results.pre-commit.ci/latest/github/jkittner/solpos-postgres/main)

# solpos-postgres

This wraps [NREL's SOLPOS 2.0](https://www.nrel.gov/grid/solar-resource/solpos.html) and makes it accessible from postgres.

The SOLPOS code was vendored from: [NREL/SolarPILOT](https://github.com/NREL/SolarPILOT/tree/21a1466398ec22db24a5a838e5133da58e347b83) which is licensed under a mixed [MIT and GPLv3license](https://github.com/jkittner/solpos/blob/master/licenses/LICENSE_SolarPILOT).

## `solar_time()`

Calculate the true solar time of a date and a location.

**Required arguments**

| **Name** | **Type** | **Description** |
| -------- | ---------------- | ------------------------------------------------ |
| `ts` | TIMESTAMPTZ | the timestamp to be converted to solar time |
| `lat` | DOUBLE PRECISION | the latitude in decimal degrees of the position |
| `lon` | DOUBLE PRECISION | the longitude in decimal degrees of the position |

```sql
SELECT solar_time('2023-10-06 15:30+00:00', 51.481, 7.217)
```

```console
solar_time
--------------------------
2023-10-06 16:10:43.7+00
```

### References

**SolarPILOT**

Wagner, M.J. (2018). "SolarPILOT Open-Source Software Project: https://github.com/NREL/SolarPILOT/tree/21a1466398ec22db24a5a838e5133da58e347b83." Accessed (27/10/2022). National Renewable Energy Laboratory, Golden, Colorado.

**Astronomical Solar Position**

Michalsky, J. 1988. The Astronomical Almanac's algorithm for approximate solar position (1950-2050). Solar Energy 40 (3), 227-235.

Michalsky, J. 1988. ERRATA: The astronomical almanac's algorithm for approximate solar position (1950-2050). Solar Energy 41 (1), 113.

**Distance from Sun to Earth**

Spencer, J. W. 1971. Fourier series representation of the position of the sun. Search 2 (5), 172. NOTE: This paper gives solar position algorithms as well, but the Michalsky/Almanac algorithm above is more accurate.

**Atmospheric Refraction Correction**

Zimmerman, John C. 1981. Sun-pointing programs and their accuracy. SAND81-0761, Experimental Systems Operation Division 4721, Sandia National Laboratories, Albuquerque, NM.

**Shadow Band Correction Factor**

Drummond, A. J. 1956. A contribution to absolute pyrheliometry. Q. J. R. Meteorol.2 Soc. 82, 481-493.

**Relative Optical Air Mass**

Kasten, F. and Young, A. 1989. Revised optical air mass tables and approximation formula. Applied Optics 28 (22), 4735-4738.

**Renormalization of KT (“PRIME”)**

Perez, R., P. Ineichen, Seals, R., & Zelenka, A. 1990. Making full use of the clearness index for parameterizing hourly insolation conditions. Solar Energy 45 (2), 111-114.

**Solar Position Relative to Earth**

Iqbal, M. 1983. An Introduction to Solar Radiation. Academic Press, NY.
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "3.8"
services:
db:
build:
context: .
args:
VERSION: ${PG_VERSION}
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: "test"
17 changes: 17 additions & 0 deletions licenses/LICENSE_solarPILOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2018 Alliance for Sustainable Energy, LLC

NOTICE: This software was developed at least in part by Alliance for Sustainable Energy, LLC (“Alliance”) under Contract No. DE-AC36-08GO28308 with the U.S. Department of Energy and the U.S. The Government retains for itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide license in the software to reproduce, prepare derivative works, distribute copies to the public, perform publicly and display publicly, and to permit others to do so.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, the above government rights notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, the above government rights notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The entire corresponding source code of any redistribution, with or without modification, by a research entity, including but not limited to any contracting manager/operator of a United States National Laboratory, any institution of higher learning, and any non-profit organization, must be made publicly available under this license for as long as the redistribution is made available by the research entity.

4. Redistribution of this software, without modification, must refer to the software by the same designation. Redistribution of a modified version of this software (i) may not refer to the modified version by the same designation, or by any confusingly similar designation, and (ii) must refer to the underlying software originally provided by Alliance as “SolarPILOT(TM)”. Except to comply with the foregoing, the terms “SolarPILOT”, “Solar Power tower Integrated Layout and Optimization Tool”, or any confusingly similar designation may not be used to refer to any modified version of this software or any modified version of the underlying software originally provided by Alliance without the prior written consent of Alliance.

5. The name of the copyright holder, contributors, the United States Government, the United States Department of Energy, or any of their employees may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, CONTRIBUTORS, UNITED STATES GOVERNMENT OR UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 changes: 45 additions & 0 deletions pg_solpos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "postgres.h"
#include "fmgr.h"
#include "solpos00.h"
#include "utils/datetime.h"
#include "utils/timestamp.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(solar_time);

Datum
solar_time(PG_FUNCTION_ARGS)
{
pg_time_t orig_time_t = timestamptz_to_time_t(PG_GETARG_TIMESTAMPTZ(0));
float8 latitude = PG_GETARG_FLOAT8(1);
float8 longitude = PG_GETARG_FLOAT8(2);
struct pg_tm *tm_result;
tm_result = pg_localtime(&orig_time_t, log_timezone);

struct posdata pd, *pdat;
pdat = &pd;
S_init(pdat);

pdat->function &= (S_TST & ~S_DOY);
pdat->year = tm_result->tm_year + 1900;
pdat->month = tm_result->tm_mon + 1;
pdat->day = tm_result->tm_mday;
pdat->hour = tm_result->tm_hour;
pdat->minute = tm_result->tm_min;
pdat->second = tm_result->tm_sec;
pdat->timezone = tm_result->tm_gmtoff;
pdat->longitude = longitude;
pdat->latitude = latitude;

long retval = S_solpos(pdat);

if (retval != 0) {
elog(ERROR, "internal error in the solpos function");
}

int64 offset = (int64)(pdat->tstfix * 60000);
TimestampTz new_time = time_t_to_timestamptz(orig_time_t);
new_time = TimestampTzPlusMilliseconds(new_time, offset);
PG_RETURN_TIMESTAMPTZ(new_time);
}
3 changes: 3 additions & 0 deletions pg_solpos.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CREATE FUNCTION solar_time(ts timestamptz, lat double precision, lon double precision) RETURNS timestamptz
AS '/usr/local/lib/funcs/pg_solpos.so', 'solar_time'
LANGUAGE C STRICT;
5 changes: 5 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
covdefaults
coverage
psycopg[binary]
pytest
pytest-docker
21 changes: 21 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[metadata]
name = solpos_posgres
long_description = file: README.md
long_description_content_type = text/markdown
license = MIT
license_files = LICENSE
classifiers =
License :: OSI Approved :: MIT License

[coverage:run]
plugins = covdefaults

[mypy]
check_untyped_defs = true
disallow_any_generics = true
disallow_incomplete_defs = true
no_implicit_optional = true
warn_unreachable = true
warn_redundant_casts = true
warn_unused_ignores = true
show_error_codes = true
Loading

0 comments on commit b8451ff

Please sign in to comment.