Skip to content

Commit

Permalink
get and create meters and meter readings (#18)
Browse files Browse the repository at this point in the history
* get and create meters and meter readings

* fix mypy

* precommit update

* remove support for 3.7
  • Loading branch information
nllong authored Feb 21, 2023
1 parent e9c3ae5 commit ae879c9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 15 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: [3.7, 3.9]
python-version: [3.9, 3.10.9]
test_env: [python, precommit, mypy]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Display system info
Expand All @@ -36,11 +36,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: "3.7"
python-version: "3.9"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ repos:
- id: mixed-line-ending
args: ["--fix=auto"]
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.0
rev: v2.0.1
hooks:
- id: autopep8
args:
Expand All @@ -35,12 +35,12 @@ repos:
"--ignore=E501,E402,W503,W504,E731",
]
- repo: https://github.com/pycqa/flake8
rev: 5.0.4
rev: 6.0.0
hooks:
- id: flake8
args: ["--ignore=E501,E402,W503,W504,E731,F401"]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
rev: v3.0.0-alpha.4
hooks:
- id: prettier
types_or: [css, yaml, markdown, html, scss, javascript]
Expand Down
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ This provides two user authentication based Python clients and two OAuth2 authen
SEED (Standard Energy Efficiency Data Platform™) is an open source "web-based application that helps organizations easily manage data on the energy performance of large groups of buildings" funded by the United States Department of Energy.

More information can be found here:

* https://energy.gov/eere/buildings/standard-energy-efficiency-data-platform
* http://seedinfo.lbl.gov/
* https://seed-platform.org
* https://github.com/SEED-platform
* https://buildingdata.energy.gov/#/seed


Note the clients do not provide per api-call methods, but does provide the standard CRUD methods: get, list, put, post, patch, delete
Expand Down
86 changes: 85 additions & 1 deletion pyseed/seed_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"""

# Imports from Standard Library
from typing import Any, Dict, List, Optional, Set, Tuple
from typing import Any, Dict, List, Optional, Set, Tuple, Union

# Imports from Third Party Modules
import json
Expand Down Expand Up @@ -947,6 +947,87 @@ def get_meters(self, property_id: int) -> list:
url_args={"PK": property_id})
return meters

def get_meter(self, property_view_id: int, meter_type: str, source: str, source_id: str) -> Union[dict, None]:
"""get a meter for a property view.
Args:
property_view_id (int): property view id
meter_type (str): Type of meter, based off the enums in the SEED Meter model
source (str): Of GreenButton, Portfolio Manager, or Custom Meter
source_id (str): Identifier, if GreenButton, then format is xpath like
Returns:
dict: meter object
"""
# return all the meters for the property and see if the meter exists, if so, return it
meters = self.get_meters(property_view_id)
for meter in meters:
if meter['type'] == meter_type and meter['source'] == source and meter['source_id'] == source_id:
return meter
else:
return None

def get_or_create_meter(self, property_view_id: int, meter_type: str, source: str, source_id: str) -> Optional[Dict[Any, Any]]:
"""get or create a meter for a property view.
Args:
property_view_id (int): property view id
meter_type (str): Type of meter, based off the enums in the SEED Meter model
source (str): Of GreenButton, Portfolio Manager, or Custom Meter
source_id (str): Identifier, if GreenButton, then format is xpath like
Returns:
dict: meter object
"""
# return all the meters for the property and see if the meter exists, if so, return it
meter = self.get_meter(property_view_id, meter_type, source, source_id)
if meter:
return meter
else:
# create the meter
payload = {
'type': meter_type,
'source': source,
'source_id': source_id,
}

meter = self.client.post(
endpoint='properties_meters', url_args={"PK": property_view_id}, json=payload
)

return meter

def delete_meter(self, property_view_id: int, meter_id: int) -> dict:
"""Delete a meter from the property.
Args:
property_view_id (int): property view id
meter_id (int): meter id
Returns:
dict: status of the delete
"""
return self.client.delete(
meter_id, endpoint='properties_meters', url_args={"PK": property_view_id}
)

def upsert_meter_readings_bulk(self, property_view_id: int, meter_id: int, data: list) -> dict:
"""Upsert meter readings for a property's meter with the bulk method.
Args:
property_id (int): property id
meter_id (int): meter id
data (list): list of dictioanries of meter readings
Returns:
dict: list of all meter reading objects
"""
# get the meter data for the property
readings = self.client.post(
endpoint='properties_meters_reading', url_args={"PK": property_view_id, "METER_PK": meter_id}, json=data
)
return readings

def get_meter_data(self, property_id, interval: str = 'Exact', excluded_meter_ids: list = []):
"""Return the meter data from the property.
Expand All @@ -962,6 +1043,9 @@ def get_meter_data(self, property_id, interval: str = 'Exact', excluded_meter_id
meter_data = self.client.post(endpoint='properties_meter_usage', url_args={"PK": property_id}, json=payload)
return meter_data

def save_meter_data(self, property_id: int, meter_id: int, meter_data) -> dict:
pass

def start_save_data(self, import_file_id: int) -> dict:
"""start the background process to save the data file to the database.
This is the state before the mapping.
Expand Down
13 changes: 9 additions & 4 deletions pyseed/seed_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@
'import_files_start_matching_pk': '/api/v3/import_files/PK/start_system_matching_and_geocoding/',
'import_files_check_meters_tab_exists_pk': '/api/v3/import_files/PK/check_meters_tab_exists/',
'org_column_mapping_import_file': 'api/v3/organizations/ORG_ID/column_mappings/',
'properties_meters_reading': '/api/v3/properties/PK/meters/METER_PK/readings/',
# GETs with replaceable keys
'import_files_matching_results': '/api/v3/import_files/PK/matching_and_geocoding_results/',
'progress': '/api/v3/progress/PROGRESS_KEY/',
'properties_meters': '/api/v3/properties/PK/meters/',
'properties_meter_usage': '/api/v3/properties/PK/meter_usage/',
'properties_meters_reading': '/api/v3/properties/PK/meters/METER_PK/readings/',
},
'v2': {
'columns': '/api/v2/columns/',
Expand Down Expand Up @@ -121,7 +123,7 @@ def _replace_url_args(url, url_args):
"""Replace any custom string URL items with values in args"""
if url_args:
for key, value in url_args.items():
url = url.replace(f"{key}/", f"{value}/")
url = url.replace(f"/{key}/", f"/{value}/")
return url


Expand Down Expand Up @@ -250,9 +252,12 @@ def _check_response(self, response, *args, **kwargs):
if error:
if response.content:
try:
error_msg = response.json().get(
'message', f"Unknown SEED Error {response.status_code}: {response.json()}"
)
if getattr(response.json(), "get", None):
error_msg = response.json().get(
'message', f"Unknown SEED Error {response.status_code}: {response.json()}"
)
else:
error_msg = f"Unknown SEED Error {response.status_code}: {response.json()}"
except ValueError:
error_msg = 'Unknown SEED Error: No response returned'
if args:
Expand Down

0 comments on commit ae879c9

Please sign in to comment.