-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from Myoldmopar/Polishing
Update so many things, major renovation, added cli, etc.
- Loading branch information
Showing
12 changed files
with
279 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ omit = | |
setup.py | ||
*distutils* | ||
*.pyenv* | ||
*pyiddidf/cli.py* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# EnergyPlus Python IDD/IDF Utilities | ||
|
||
Python library of EnergyPlus IDD/IDF manipulation utilities. | ||
|
||
## Documentation | ||
|
||
[![Documentation Status](https://readthedocs.org/projects/energyplus-idd-idf/badge/?version=latest)](https://energyplus-idd-idf.readthedocs.io/en/latest/?badge=latest) | ||
|
||
Documentation is hosted on ReadTheDocs at https://energyplus-idd-idf.readthedocs.io/en/latest/. | ||
To build the documentation, enter the docs/ subdirectory and execute `make html`; then open | ||
`/docs/_build/html/index.html` to see the documentation. | ||
|
||
## Installation | ||
|
||
This package is deployed to PyPi at https://badge.fury.io/py/energyplus-idd-idf-utilities. | ||
To install, simply `pip install energyplus-idd-idf-utilities`. | ||
|
||
## Basic Usage | ||
|
||
Once installed, the utilities are available for use as a library of functionality to call from Python, or with a very limited (for now) CLI called `energyplus_idd_idf`. | ||
Some example CLI calls: | ||
|
||
Get the CLI form: | ||
|
||
```shell | ||
$ ./some_python_venv/bin/energyplus_idd_idf --help | ||
usage: energyplus_idd_idf [-h] [--idd_check] [--idd_obj_matches IDD_OBJ_MATCHES] [--summarize_idd_object SUMMARIZE_IDD_OBJECT] filename | ||
|
||
EnergyPlus IDD/IDF Utility Command Line | ||
|
||
positional arguments: | ||
filename Path to IDD/IDF file to be operated upon | ||
|
||
optional arguments: | ||
-h, --help show this help message and exit | ||
--idd_check Process the given IDD file and report statistics and issues | ||
--idd_obj_matches IDD_OBJ_MATCHES | ||
Find IDD objects that match the given basic pattern | ||
--summarize_idd_object SUMMARIZE_IDD_OBJECT | ||
Print a summary of a single IDD object by name | ||
|
||
This CLI is in infancy and will probably have features added over time | ||
|
||
``` | ||
|
||
Check an existing IDD file and get basic information: | ||
|
||
```shell | ||
$ ./some_python_venv/bin/energyplus_idd_idf --idd_check /path/to/EnergyPlus-22-2-0/Energy+.idd | ||
{ | ||
"message": "Everything looks OK", | ||
"content": { | ||
"idd_version": "22.2.0", | ||
"idd_build_id": "c249759bad", | ||
"num_groups": 59, | ||
"num_objects": 881 | ||
} | ||
} | ||
|
||
``` | ||
|
||
Find all objects which match a certain name pattern: | ||
|
||
```shell | ||
$ ./some_python_venv/bin/energyplus_idd_idf --idd_obj_matches 'Coil:Cooling*' /path/to/EnergyPlus-22-2-0/Energy+.idd | ||
{ | ||
"message": "Everything looks OK", | ||
"content": { | ||
"pattern": "Coil:Cooling*", | ||
"matching_objects": [ | ||
"Coil:Cooling:Water", | ||
"Coil:Cooling:Water:DetailedGeometry", | ||
"Coil:Cooling:DX", | ||
"Coil:Cooling:DX:CurveFit:Performance", | ||
"Coil:Cooling:DX:CurveFit:OperatingMode", | ||
"Coil:Cooling:DX:CurveFit:Speed", | ||
"Coil:Cooling:DX:SingleSpeed", | ||
"Coil:Cooling:DX:TwoSpeed", | ||
"Coil:Cooling:DX:MultiSpeed", | ||
"Coil:Cooling:DX:VariableSpeed", | ||
"Coil:Cooling:DX:TwoStageWithHumidityControlMode", | ||
"Coil:Cooling:DX:VariableRefrigerantFlow", | ||
"Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl", | ||
"Coil:Cooling:WaterToAirHeatPump:ParameterEstimation", | ||
"Coil:Cooling:WaterToAirHeatPump:EquationFit", | ||
"Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", | ||
"Coil:Cooling:DX:SingleSpeed:ThermalStorage" | ||
] | ||
} | ||
} | ||
|
||
``` | ||
|
||
Get specific details about a single object by name: | ||
|
||
```shell | ||
$ ./some_python_venv/bin/energyplus_idd_idf /path/to/EnergyPlus-22-2-0/Energy+.idd --summarize_idd_object "Coil:Cooling:DX" | ||
{ | ||
"message": "Everything looks OK", | ||
"content": { | ||
"searched_object_name": "COIL:COOLING:DX", | ||
"field": [ | ||
"A1 : Name", | ||
"A2 : Evaporator Inlet Node Name", | ||
"A3 : Evaporator Outlet Node Name", | ||
"A4 : Availability Schedule Name", | ||
"A5 : Condenser Zone Name", | ||
"A6 : Condenser Inlet Node Name", | ||
"A7 : Condenser Outlet Node Name", | ||
"A8 : Performance Object Name", | ||
"A9 : Condensate Collection Water Storage Tank Name", | ||
"A10 : Evaporative Condenser Supply Water Storage Tank Name" | ||
] | ||
} | ||
} | ||
``` | ||
|
||
## Testing | ||
|
||
[![Flake8](https://github.com/Myoldmopar/py-idd-idf/actions/workflows/flake8.yml/badge.svg)](https://github.com/Myoldmopar/py-idd-idf/actions/workflows/flake8.yml) | ||
[![Run Tests](https://github.com/Myoldmopar/py-idd-idf/actions/workflows/test.yml/badge.svg)](https://github.com/Myoldmopar/py-idd-idf/actions/workflows/test.yml) | ||
|
||
The source is tested using the python unittest framework. | ||
To execute all the unit tests, simply run `nosetests` from the project root. | ||
The tests are also executed by GitHub Actions for each commit. | ||
|
||
## Test Coverage | ||
|
||
[![Coverage Status](https://coveralls.io/repos/github/Myoldmopar/py-idd-idf/badge.svg?branch=master)](https://coveralls.io/github/Myoldmopar/py-idd-idf?branch=master) | ||
|
||
Coverage of the code from unit testing is reported to Coveralls at https://coveralls.io/github/Myoldmopar/py-idd-idf. | ||
Anything less than 100% coverage will be frowned upon. :) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
from argparse import ArgumentParser | ||
from fnmatch import fnmatch | ||
from json import dumps | ||
from functools import reduce | ||
from pathlib import Path | ||
from sys import exit | ||
from typing import Optional | ||
|
||
from pyiddidf.exceptions import ProcessingException | ||
from pyiddidf.idd_objects import IDDObject | ||
from pyiddidf.idd_processor import IDDProcessor | ||
|
||
|
||
class Actions: | ||
IDDCheck = 'idd_check' | ||
FindIDDObjectsMatching = 'find_idd_objects_matching' | ||
SummarizeIDDObject = 'summarize_idd_object' | ||
|
||
|
||
class ExitCodes: | ||
OK = 0 | ||
ProcessingError = 1 | ||
BadArguments = 2 | ||
|
||
|
||
# Eventually this could become a more feature rich CLI | ||
def main_cli() -> int: | ||
parser = ArgumentParser( | ||
prog="energyplus_idd_idf", | ||
description="EnergyPlus IDD/IDF Utility Command Line", | ||
epilog="This CLI is in infancy and will probably have features added over time" | ||
) | ||
parser.add_argument('filename', help="Path to IDD/IDF file to be operated upon") # positional argument | ||
parser.add_argument( | ||
'--idd_check', action='store_const', const=Actions.IDDCheck, | ||
help="Process the given IDD file and report statistics and issues" | ||
) | ||
parser.add_argument( | ||
'--idd_obj_matches', type=str, help="Find IDD objects that match the given basic pattern" | ||
) | ||
parser.add_argument( | ||
'--summarize_idd_object', type=str, help="Print a summary of a single IDD object by name" | ||
) | ||
args = parser.parse_args() | ||
all_options = [ | ||
args.idd_check, args.idd_obj_matches, args.summarize_idd_object | ||
] | ||
if all([x is None for x in all_options]): | ||
print(dumps({'message': "Nothing to do...use command line switches to perform operations"}, indent=2)) | ||
return ExitCodes.OK | ||
p = Path(args.filename) | ||
if not p.exists(): | ||
print(dumps({'message': "Supplied file does not appear to exist, check paths and retry!"}, indent=2)) | ||
return ExitCodes.BadArguments | ||
# for now assume it's always the IDD so we don't have to repeat this code | ||
processor = IDDProcessor() | ||
try: | ||
processor.process_file_given_file_path(str(p)) | ||
except ProcessingException: | ||
print("Issues occurred during processing") | ||
return ExitCodes.ProcessingError | ||
if args.idd_check: | ||
num_groups = len(processor.idd.groups) | ||
num_objects = reduce( | ||
lambda x, y: x + y, | ||
[len(g.objects) for g in processor.idd.groups], | ||
0 | ||
) | ||
print(dumps({ | ||
'message': 'Everything looks OK', | ||
'content': { | ||
'idd_version': processor.idd.version_string, | ||
'idd_build_id': processor.idd.build_string, | ||
'num_groups': num_groups, | ||
'num_objects': num_objects | ||
} | ||
}, indent=2)) | ||
elif args.idd_obj_matches: | ||
pattern = args.iddobjmatches | ||
matching_objects = [] | ||
for g in processor.idd.groups: | ||
for o in g.objects: | ||
obj_name = o.name | ||
if fnmatch(obj_name, pattern): | ||
matching_objects.append(o) | ||
print(dumps({ | ||
'message': 'Everything looks OK', | ||
'content': { | ||
'pattern': pattern, | ||
'matching_objects': [ | ||
o.name for o in matching_objects | ||
] | ||
} | ||
}, indent=2)) | ||
elif args.summarize_idd_object: | ||
object_name = args.summarize_idd_object.upper() | ||
matching_object: Optional[IDDObject] = None | ||
for g in processor.idd.groups: | ||
for o in g.objects: | ||
obj_name = o.name.upper() | ||
if fnmatch(obj_name, object_name): | ||
matching_object = o | ||
if matching_object is None: | ||
print(dumps({'message': f"Could not find matching object by name {object_name}"}, indent=2)) | ||
return ExitCodes.BadArguments | ||
print(dumps({ | ||
'message': 'Everything looks OK', | ||
'content': { | ||
'searched_object_name': object_name, | ||
'field': [ | ||
f"{f.field_an_index} : {f.field_name}" for f in matching_object.fields | ||
] | ||
} | ||
}, indent=2)) | ||
return ExitCodes.OK | ||
|
||
|
||
if __name__ == "__main__": # pragma: no cover | ||
exit(main_cli()) |
Oops, something went wrong.