diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5647b9a --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +# Created by .ignore support plugin (hsz.mobi) +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + diff --git a/README.md b/README.md index 75bed91..89b5363 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ # EnphaseInterface Python implementation interface to the Enphase Developer API + +## Installation + +`python3 -m pip install pyenface` + +## Usage + +```python +from pyEnFace.EnphaseInterface import PandasEnphaseInterface + +client = client = PandasEnphaseInterface(userId=, api_key=) + +# Request all systems +client.index() + +# Request inventory +client.inventory(system_id=) + +# Summary +client.summary(system_id=) + +# Get data as pandas dataframe +start = pd.Timestamp('20180101') + +client.energy_lifetime(system_id=, start_date=start) +``` \ No newline at end of file diff --git a/pyEnFace/EnphaseInterface.py b/pyEnFace/EnphaseInterface.py index bd20765..d1e77cb 100644 --- a/pyEnFace/EnphaseInterface.py +++ b/pyEnFace/EnphaseInterface.py @@ -151,7 +151,7 @@ class RawEnphaseInterface(object): def __init__(self, userId, max_wait=DEFAULT_MAX_WAIT, useragent='Mozilla/5.0', datetimeType=DateTimeType.Enphase, - errorhandler=None): + errorhandler=None, api_key=None): if errorhandler==None: errorhandler=EnphaseErrorHandler(datetimeType,max_wait) @@ -165,6 +165,9 @@ def __init__(self, userId, max_wait=DEFAULT_MAX_WAIT, self.opener.addheaders = [('User-agent',useragent)] self.apiDest = APIV2 + if api_key is not None: + APIKEYRING.append(api_key) + def _execQuery(self, system_id, command, extraParams = dict()): '''Generates a request url for the Enphase API''' @@ -259,6 +262,12 @@ def energy_lifetime(self, system_id, **kwargs): validArgs = self._filterAttributes(('start_date','end_date'),kwargs) return self._execQuery(system_id, 'energy_lifetime', validArgs) + def consumption_lifetime(self, system_id, **kwargs): + """Get the lifetime energy consumption measured by the system""" + + validArgs = self._filterAttributes(('start_date','end_date'), kwargs) + return self._execQuery(system_id, 'consumption_lifetime', validArgs) + def envoys(self, system_id, **kwargs): '''List the envoys associated with the system''' @@ -328,6 +337,8 @@ def _execQuery(self, system_id, command, extraParams = dict()): if command == 'energy_lifetime': output = self._energy_lifetime(data) + elif command == 'consumption_lifetime': + output = self._consumption_lifetime(data) elif command == 'envoys': output = self._envoys(data) elif command == 'index' or command == '': @@ -348,15 +359,22 @@ def _execQuery(self, system_id, command, extraParams = dict()): indexes = output.index.names return self._datetimeify(output).set_index(indexes) - def _energy_lifetime(self,data): - d = json_normalize(data, 'production',['start_date','system_id']) - ts = to_timedelta(Series(d.index),unit='D') - d['start_date'] = to_datetime(d['start_date'],unit='s') + ts + def _lifetime(self, data, column): + """column can be 'production', or 'consumption'""" + d = json_normalize(data, column, ['start_date', 'system_id']) + ts = to_timedelta(Series(d.index), unit='D') + d['start_date'] = to_datetime(d['start_date']) + ts d['start_date'] = d['start_date'].apply( - lambda x:self.dtt.stringify('start_date',x)) - d.rename(columns={0:'production'},inplace=True) + lambda x: self.dtt.stringify('start_date', x)) + d.rename(columns={0: column}, inplace=True) + + return d.set_index(['system_id', 'start_date']) + + def _energy_lifetime(self, data): + return self._lifetime(data, "production") - return d.set_index(['system_id','start_date']) + def _consumption_lifetime(self, data): + return self._lifetime(data, "consumption") def _envoys(self,data): return json_normalize(data, 'envoys',