Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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 CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Run poetry against a single file with:
*\*From the root of the project\**

```sh
poetry run pytest tests/turbines/turbines_test.py`
poetry run pytest tests/turbines/turbines_test.py
```

### Code Style
Expand Down
1 change: 1 addition & 0 deletions cwms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from cwms.timeseries.timeseries_profile_instance import *
from cwms.timeseries.timeseries_profile_parser import *
from cwms.timeseries.timeseries_txt import *
from cwms.turbines.turbines import *

try:
__version__ = version("cwms-python")
Expand Down
242 changes: 242 additions & 0 deletions cwms/turbines/turbines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
from datetime import datetime
from typing import Optional

import cwms.api as api
from cwms.cwms_types import JSON, Data

# ==========================================================================
# GET CWMS TURBINES
# ==========================================================================


def get_project_turbines(office: str, project_id: str) -> Data:
"""Returns matching CWMS Turbine Data for a Reservoir Project. Get cwmsData projects turbines.
Args:
office (str): The office associated with the turbine data.
project_id (str): The ID of the project.
Returns:
dict: A dictionary containing the turbine data.
"""
endpoint = "projects/turbines"
params = {"office": office, "project-id": project_id}

response = api.get(endpoint=endpoint, params=params)

return Data(response)


def get_project_turbine(office: str, name: str) -> Data:
"""Returns CWMS Turbine Data Get cwmsData projects turbines with name.
Args:
office (str): The office associated with the turbine data.
name (str): The name of the turbine.
Returns:
dict: A dictionary containing the turbine data.
"""
endpoint = f"projects/turbines/{name}"
params = {"office": office}
response = api.get(endpoint=endpoint, params=params)
return Data(response)


def get_project_turbine_changes(
name: str,
begin: datetime,
end: datetime,
office: str,
page_size: Optional[int],
unit_system: Optional[str],
start_time_inclusive: Optional[bool],
end_time_inclusive: Optional[bool],
) -> Data:
"""
Returns CWMS Turbine Data for projects with specified office and turbine name changes within a given time range.
Args:
begin (str): The start date and time for the data retrieval in ISO 8601 format.
end (str): The end date and time for the data retrieval in ISO 8601 format.
end_time_inclusive (Optional[bool]): Whether the end time is inclusive.
name (str): The name of the turbine.
office (str): The office associated with the turbine data.
page_size (Optional[int]): The number of records to return per page.
start_time_inclusive (Optional[bool]): Whether the start time is inclusive.
unit_system (Optional[str]): The unit system to use for the data [SI, EN].
Returns:
dict: A dictionary containing the turbine data.
"""
if begin and not isinstance(begin, datetime):
raise ValueError("begin needs to be in datetime")
if end and not isinstance(end, datetime):
raise ValueError("end needs to be in datetime")

endpoint = f"projects/{office}/{name}/turbine-changes"
params = {
"name": name,
"begin": begin.isoformat() if begin else None,
"end": end.isoformat() if end else None,
"office": office,
"page-size": page_size,
"unit-system": unit_system,
"start-time-inclusive": start_time_inclusive,
"end-time-inclusive": end_time_inclusive,
}
response = api.get(endpoint=endpoint, params=params)
return Data(response)


# ==========================================================================
# POST CWMS TURBINES
# ==========================================================================


def store_project_turbine(data: JSON, fail_if_exists: Optional[bool]) -> None:
"""
Create a new turbine in CWMS.
Parameters
----------
fail_if_exists (bool): If True, the request will fail if the turbine already exists.

Returns
-------
None


Raises
------
ValueError
If provided data is None
Unauthorized
401 - Indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
Forbidden
403 - Indicates that the server understands the request but refuses to authorize it.
Not Found
404 - Indicates that the server cannot find the requested resource.
Server Error
500 - Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
"""
if data is None:
raise ValueError(
"Cannot store project turbine changes without a JSON data dictionary"
)
endpoint = "projects/turbines"
params = {
"fail-if-exists": fail_if_exists,
}
return api.post(endpoint=endpoint, data=data, params=params)


def store_project_turbine_changes(
data: JSON, office: str, name: str, override_protection: Optional[bool]
) -> None:
"""
Create CWMS Turbine Changes
Parameters
----------
office (str): Office id for the reservoir project location associated with the turbine changes.
name (str): Specifies the name of project of the Turbine changes whose data is to stored.
override_protection (bool): A flag ('True'/'False') specifying whether to delete protected data. Default is False

Returns
-------
None - Turbine successfully stored to CWMS.


Raises
------
ValueError
If provided data is None
Unauthorized
401 - Indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
Forbidden
403 - Indicates that the server understands the request but refuses to authorize it.
Not Found
404 - Indicates that the server cannot find the requested resource.
Server Error
500 - Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
"""
if data is None:
raise ValueError(
"Cannot store project turbine changes without a JSON data dictionary"
)
endpoint = f"projects/{office}/{name}/turbine-changes"
params = {"override-protection": override_protection}
return api.post(endpoint=endpoint, data=data, params=params)


# ==========================================================================
# DELETE CWMS TURBINES
# ==========================================================================


def delete_project_turbine(name: str, office: str, method: Optional[str]) -> None:
"""
Delete CWMS Turbine
Parameters
----------
name (str): Specifies the name of the turbine to be deleted.
office (str): Specifies the owning office of the turbine to be deleted.
method (str): Specifies the delete method used. Defaults to "DELETE_KEY". Options are: DELETE_KEY, DELETE_DATA, DELETE_ALL
Returns
-------
None - Turbine successfully deleted from CWMS.


Raises
------
ValueError
If provided data is None
Unauthorized
401 - Indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
Forbidden
403 - Indicates that the server understands the request but refuses to authorize it.
Not Found
404 - Indicates that the server cannot find the requested resource.
Server Error
500 - Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
"""
endpoint = f"projects/turbines/{name}"
params = {"office": office, "method": method}
return api.delete(endpoint=endpoint, params=params, api_version=1)


def delete_project_turbine_changes(
office: str,
name: str,
begin: datetime,
end: datetime,
override_protection: Optional[bool],
) -> None:
"""
Delete CWMS Turbine Changes
Parameters
----------
name (str): Specifies the name of project for the turbine changes to be deleted.
office (str): Specifies the owning office of the turbine to be deleted.
begin (datetime): The start of the time window
end (datetime): The end of the time window
override_protection (bool): A flag ('True'/'False') specifying whether to delete protected data. Default is False

Returns
-------
None - Turbine successfully deleted from CWMS.


Raises
------
ValueError
If provided data is None
Unauthorized
401 - Indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
Forbidden
403 - Indicates that the server understands the request but refuses to authorize it.
Not Found
404 - Indicates that the server cannot find the requested resource.
Server Error
500 - Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
"""
endpoint = f"projects/{office}/{name}/turbine-changes"
params = {
"begin": begin.isoformat() if begin else None,
"end": end.isoformat() if end else None,
"override-protection": override_protection,
}
return api.delete(endpoint=endpoint, params=params, api_version=1)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cwms-python"
version = "0.5.2"
version = "0.5.3"
packages = [
{ include = "cwms" },
]
Expand Down
58 changes: 58 additions & 0 deletions tests/resources/turbines.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"project-id": {
"office-id": "SWT",
"name": "KEYS"
},
"location": {
"office-id": "SWT",
"name": "KEYS-Turbine1",
"latitude": 36.1506371,
"longitude": -96.2525088,
"active": true,
"public-name": "Turbine1",
"long-name": "Turbine1",
"timezone-name": "US/Central",
"location-kind": "TURBINE",
"nation": "US",
"state-initial": "OK",
"county-name": "Tulsa",
"nearest-city": "Sand Springs, OK",
"horizontal-datum": "NAD83",
"published-longitude": 0,
"published-latitude": 0,
"vertical-datum": "NGVD29",
"elevation": 0,
"bounding-office-id": "SWT",
"elevation-units": "m"
}
},
{
"project-id": {
"office-id": "SWT",
"name": "KEYS"
},
"location": {
"office-id": "SWT",
"name": "KEYS-Turbine2",
"latitude": 36.1506371,
"longitude": -96.2525088,
"active": true,
"public-name": "Turbine2",
"long-name": "Turbine2",
"timezone-name": "US/Central",
"location-kind": "TURBINE",
"nation": "US",
"state-initial": "OK",
"county-name": "Tulsa",
"nearest-city": "Sand Springs, OK",
"horizontal-datum": "NAD83",
"published-longitude": 0,
"published-latitude": 0,
"vertical-datum": "NGVD29",
"elevation": 0,
"bounding-office-id": "SWT",
"elevation-units": "m"
}
}
]
28 changes: 28 additions & 0 deletions tests/resources/turbines_name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"project-id": {
"office-id": "SWT",
"name": "KEYS"
},
"location": {
"office-id": "SWT",
"name": "KEYS-Turbine1",
"latitude": 36.1506371,
"longitude": -96.2525088,
"active": true,
"public-name": "Turbine1",
"long-name": "Turbine1",
"timezone-name": "US/Central",
"location-kind": "TURBINE",
"nation": "US",
"state-initial": "OK",
"county-name": "Tulsa",
"nearest-city": "Sand Springs, OK",
"horizontal-datum": "NAD83",
"published-longitude": 0,
"published-latitude": 0,
"vertical-datum": "NGVD29",
"elevation": 0,
"bounding-office-id": "SWT",
"elevation-units": "m"
}
}
Loading