diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..30e0b97 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +version: 2 +updates: +- package-ecosystem: pip + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + ignore: + - dependency-name: pytest + - dependency-name: setuptools + - dependency-name: twine + - dependency-name: wheel + commit-message: + prefix: fix + prefix-development: chore + include: scope diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..a4a353e --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,26 @@ +--- +name: CI + +on: [pull_request] + +jobs: + + test: + name: Unit tests + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + - name: set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: install python dependencies + run: | + pip install -r dev-requirements.txt + pip install . + - name: run tests + run: python -m pytest tests/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38eff34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +*.pyc +test.py +.pytest_cache +*__pycache__ +.coverage +*.ipynb +.ipynb_checkpoints +.tox +*.egg-info +tox.ini +/.cache +/.vscode +.eggs +*.code-workspace + +venv +test.py +dist/ +build/ diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..8002347 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,19 @@ +{ + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/github", + { + "successComment": false, + "failTitle": false + } + ], + [ + "@semantic-release/exec", + { + "publishCmd": "bash deploy.sh" + } + ] + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3f09b05 --- /dev/null +++ b/LICENSE @@ -0,0 +1,164 @@ +# PolyForm Shield License 1.0.0 + + + +## Acceptance + +In order to get any license under these terms, you must agree +to them as both strict obligations and conditions to all +your licenses. + +## Copyright License + +The licensor grants you a copyright license for the +software to do everything you might do with the software +that would otherwise infringe the licensor's copyright +in it for any permitted purpose. However, you may +only distribute the software according to [Distribution +License](#distribution-license) and make changes or new works +based on the software according to [Changes and New Works +License](#changes-and-new-works-license). + +## Distribution License + +The licensor grants you an additional copyright license +to distribute copies of the software. Your license +to distribute covers distributing the software with +changes and new works permitted by [Changes and New Works +License](#changes-and-new-works-license). + +## Notices + +You must ensure that anyone who gets a copy of any part of +the software from you also gets a copy of these terms or the +URL for them above, as well as copies of any plain-text lines +beginning with `Required Notice:` that the licensor provided +with the software. For example: + +> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) + +## Changes and New Works License + +The licensor grants you an additional copyright license to +make changes and new works based on the software for any +permitted purpose. + +## Patent License + +The licensor grants you a patent license for the software that +covers patent claims the licensor can license, or becomes able +to license, that you would infringe by using the software. + +## Noncompete + +Any purpose is a permitted purpose, except for providing any +product that competes with the software or any product the +licensor or any of its affiliates provides using the software. + +## Competition + +Goods and services compete even when they provide functionality +through different kinds of interfaces or for different technical +platforms. Applications can compete with services, libraries +with plugins, frameworks with development tools, and so on, +even if they're written in different programming languages +or for different computer architectures. Goods and services +compete even when provided free of charge. If you market a +product as a practical substitute for the software or another +product, it definitely competes. + +## New Products + +If you are using the software to provide a product that does +not compete, but the licensor or any of its affiliates brings +your product into competition by providing a new version of +the software or another product using the software, you may +continue using versions of the software available under these +terms beforehand to provide your competing product, but not +any later versions. + +## Discontinued Products + +You may begin using the software to compete with a product +or service that the licensor or any of its affiliates has +stopped providing, unless the licensor includes a plain-text +line beginning with `Licensor Line of Business:` with the +software that mentions that line of business. For example: + +> Licensor Line of Business: YoyodyneCMS Content Management +System (http://example.com/cms) + +## Sales of Business + +If the licensor or any of its affiliates sells a line of +business developing the software or using the software +to provide a product, the buyer can also enforce +[Noncompete](#noncompete) for that product. + +## Fair Use + +You may have "fair use" rights for the software under the +law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of +your licenses to anyone else, or prevent the licensor from +granting licenses to anyone else. These terms do not imply +any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or +contributes to infringement of any patent, your patent license +for the software granted under these terms ends immediately. If +your company makes such a claim, your patent license ends +immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have +violated any of these terms, or done anything with the software +not covered by your licenses, your licenses can nonetheless +continue if you come into full compliance with these terms, +and take practical steps to correct past violations, within +32 days of receiving notice. Otherwise, all your licenses +end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without +any warranty or condition, and the licensor will not be liable +to you for any damages arising out of these terms or the use +or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these +terms, and the **software** is the software the licensor makes +available under these terms. + +A **product** can be a good or service, or a combination +of them. + +**You** refers to the individual or entity agreeing to these +terms. + +**Your company** is any legal entity, sole proprietorship, +or other kind of organization that you work for, plus all +its affiliates. + +**Affiliates** means the other organizations than an +organization has control over, is under the control of, or is +under common control with. + +**Control** means ownership of substantially all the assets of +an entity, or the power to direct its management and policies +by vote, contract, or otherwise. Control can be direct or +indirect. + +**Your licenses** are all the licenses granted to you for the +software under these terms. + +**Use** means anything you do with the software requiring one +of your licenses. diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..057a123 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "Building distribution" +python setup.py sdist bdist_wheel +echo "Pushing new version to PyPi" +twine upload dist/* -u $PYPI_USERNAME -p $PYPI_PASSWORD diff --git a/dev-requirements.txt b/dev-requirements.txt new file mode 100644 index 0000000..8805d9b --- /dev/null +++ b/dev-requirements.txt @@ -0,0 +1,4 @@ +pytest==6.2.5 +twine==3.4.1 +wheel==0.36.2 +setuptools==56.0.0 diff --git a/pollination/breeam_daylight_4b/__init__.py b/pollination/breeam_daylight_4b/__init__.py new file mode 100644 index 0000000..897eb89 --- /dev/null +++ b/pollination/breeam_daylight_4b/__init__.py @@ -0,0 +1,6 @@ +from .entry import BreeamDaylight4bEntryPoint + + +__pollination__ = { + 'entry_point': BreeamDaylight4bEntryPoint +} diff --git a/pollination/breeam_daylight_4b/entry.py b/pollination/breeam_daylight_4b/entry.py new file mode 100644 index 0000000..6d98608 --- /dev/null +++ b/pollination/breeam_daylight_4b/entry.py @@ -0,0 +1,108 @@ +from pollination_dsl.dag import Inputs, DAG, task, Outputs +from dataclasses import dataclass +from pollination.two_phase_daylight_coefficient import TwoPhaseDaylightCoefficientEntryPoint +from pollination.honeybee_radiance_postprocess.breeam import Breeam4b + +# input/output alias +from pollination.alias.inputs.model import hbjson_model_grid_input +from pollination.alias.inputs.wea import wea_input_timestep_check +from pollination.alias.inputs.north import north_input +from pollination.alias.inputs.radiancepar import rad_par_annual_input +from pollination.alias.inputs.grid import grid_filter_input, \ + min_sensor_count_input, cpu_count + + +@dataclass +class BreeamDaylight4bEntryPoint(DAG): + """BREEAM daylight 4b entry point.""" + + # inputs + north = Inputs.float( + default=0, + description='A number between -360 and 360 for the counterclockwise ' + 'difference between the North and the positive Y-axis in degrees. This ' + 'can also be a Vector for the direction to North. (Default: 0).', + spec={'type': 'number', 'minimum': -360, 'maximum': 360}, + alias=north_input + ) + + cpu_count = Inputs.int( + default=50, + description='The maximum number of CPUs for parallel execution. This will be ' + 'used to determine the number of sensors run by each worker.', + spec={'type': 'integer', 'minimum': 1}, + alias=cpu_count + ) + + min_sensor_count = Inputs.int( + description='The minimum number of sensors in each sensor grid after ' + 'redistributing the sensors based on cpu_count. This value takes ' + 'precedence over the cpu_count and can be used to ensure that ' + 'the parallelization does not result in generating unnecessarily small ' + 'sensor grids. The default value is set to 1, which means that the ' + 'cpu_count is always respected.', default=500, + spec={'type': 'integer', 'minimum': 1}, + alias=min_sensor_count_input + ) + + radiance_parameters = Inputs.str( + description='The radiance parameters for ray tracing.', + default='-ab 2 -ad 5000 -lw 2e-05 -dr 0', + alias=rad_par_annual_input + ) + + grid_filter = Inputs.str( + description='Text for a grid identifier or a pattern to filter the sensor grids ' + 'of the model that are simulated. For instance, first_floor_* will simulate ' + 'only the sensor grids that have an identifier that starts with ' + 'first_floor_. By default, all grids in the model will be simulated.', + default='*', + alias=grid_filter_input + ) + + model = Inputs.file( + description='A Honeybee Model JSON file (HBJSON) or a Model pkl (HBpkl) file. ' + 'This can also be a zipped version of a Radiance folder, in which case this ' + 'recipe will simply unzip the file and simulate it as-is.', + extensions=['json', 'hbjson', 'pkl', 'hbpkl', 'zip'], + alias=hbjson_model_grid_input + ) + + wea = Inputs.file( + description='Wea file.', + extensions=['wea', 'epw'], + alias=wea_input_timestep_check + ) + + @task( + template=TwoPhaseDaylightCoefficientEntryPoint + ) + def run_two_phase_daylight_coefficient( + self, north=north, cpu_count=cpu_count, min_sensor_count=min_sensor_count, + radiance_parameters=radiance_parameters, grid_filter=grid_filter, + model=model, wea=wea + ): + pass + + @task( + template=Breeam4b, + needs=[run_two_phase_daylight_coefficient] + ) + def leed_daylight_option_one( + self, folder='results', model=model + ): + return [ + { + 'from': Breeam4b()._outputs.breeam_summary, + 'to': 'breeam_summary' + } + ] + + results = Outputs.folder( + source='results', description='Folder with raw result files (.ill) that ' + 'contain illuminance matrices for each sensor at each timestep of the analysis.' + ) + + breeam_summary = Outputs.folder( + source='breeam_summary', description='BREEAM summary folder.' + ) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5475a4d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pollination-two-phase-daylight-coefficient==1.1.32 +pollination-honeybee-radiance-postprocess==0.0.72 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..ed8a958 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +universal = 1 + +[metadata] +license_file = LICENSE diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..5a939f7 --- /dev/null +++ b/setup.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +import setuptools + +with open("README.md", "r") as fh: + long_description = fh.read() + +with open('requirements.txt') as f: + requirements = f.read().splitlines() + requirements = [req.replace('==', '>=') for req in requirements] + +# normal setuptool inputs +setuptools.setup( + name='pollination-breeam-daylight-4b', # will be used for package name unless it is overwritten using __queenbee__ info. + author='pollination', # the owner account for this package - required if pushed to Pollination + author_email='info@pollination.solutions', + packages=setuptools.find_namespace_packages( # required - that's how pollination find the package + include=['pollination.*'], exclude=['tests', '.github'] + ), + install_requires=requirements, + use_scm_version=True, + setup_requires=['setuptools_scm'], + url='https://github.com/pollination/breeam-daylight-4b', # will be translated to home + project_urls={ + 'icon': 'https://raw.githubusercontent.com/ladybug-tools/artwork/master/icons_components/honeybee/png/leeddaylight.png', + 'docker': 'https://hub.docker.com/r/ladybugtools/honeybee-radiance' + }, + description='BREEAM daylight 4b recipe for Pollination.', # will be used as package description + long_description=long_description, # will be translated to ReadMe content on Pollination + long_description_content_type="text/markdown", + maintainer='mikkel, pollination', # Package maintainers. For multiple maintainers use comma + maintainer_email='mikkel@ladybug.tools, info@pollination.solutions', + keywords='honeybee, radiance, ladybug-tools, daylight, annual-daylight, breeam-daylight-4b', # will be used as keywords + license='PolyForm Shield License 1.0.0, https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt', # the license link should be separated by a comma + zip_safe=False +) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/validation_test.py b/tests/validation_test.py new file mode 100644 index 0000000..394bd2a --- /dev/null +++ b/tests/validation_test.py @@ -0,0 +1,8 @@ +from pollination.breeam_daylight_4b.entry import BreeamDaylight4bEntryPoint +from queenbee.recipe.dag import DAG + + +def test_breeam_daylight_4b(): + recipe = BreeamDaylight4bEntryPoint().queenbee + assert recipe.name == 'breeam-daylight-4b-entry-point' + assert isinstance(recipe, DAG)