Skip to content

Commit

Permalink
Merge cdfa2f0 into 2486b5b
Browse files Browse the repository at this point in the history
  • Loading branch information
aguinane committed Mar 22, 2024
2 parents 2486b5b + cdfa2f0 commit 4d13615
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 149 deletions.
5 changes: 0 additions & 5 deletions .flake8

This file was deleted.

13 changes: 4 additions & 9 deletions .github/workflows/pythonpackage.yml
@@ -1,13 +1,14 @@
name: Python package

on: ["push", "pull_request"]
on: ["pull_request"]

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -20,19 +21,13 @@ jobs:
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# install the local folder
python -m pip install -e .
- name: Lint with flake8
run: |
pip install flake8
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pip install pytest pytest-cov
pytest --cov=nemwriter --cov-report=xml
- name: Coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: |
pip install coveralls
Expand Down
7 changes: 6 additions & 1 deletion README.md
Expand Up @@ -77,6 +77,11 @@ output = m.output_zip(file_path='output.zip')
If you create a pandas DataFrame, for example:

```python
from datetime import datetime, timedelta
from nemwriter import NEM12
from random import randrange
import pandas as pd

num_intervals = 288
index = [datetime(2004, 4, 1) + timedelta(minutes=5*x) for x in range(1,num_intervals+1)]
e1 = [randrange(1,10) for x in range(1,num_intervals+1)]
Expand Down Expand Up @@ -105,7 +110,7 @@ print(df)
You can easily output the dataframe to a NEM12 file:
```python
m = NEM12(to_participant='123')
m.add_dataframe(nmi='123', interval=5, df=df, uoms={'E1': 'kWh', 'E2': 'kWh'})
m.add_dataframe(nmi='123', df=df, uoms={'E1': 'kWh', 'E2': 'kWh'})
output = m.output_csv(file_path='output.csv')
```

Expand Down
16 changes: 6 additions & 10 deletions nemwriter/nem12_writer.py
Expand Up @@ -61,7 +61,7 @@ def remove_zero_decimal(x: float) -> Union[float, int]:
return int(x)


class NEM12(object):
class NEM12:
"""An NEM file object"""

def __init__(
Expand All @@ -83,7 +83,7 @@ def __init__(
self.days = []

def __repr__(self):
return "<NEM12 Builder {} {}>".format(self.file_time, self.to_participant)
return f"<NEM12 Builder {self.file_time} {self.to_participant}>"

@property
def is_empty(self) -> bool:
Expand Down Expand Up @@ -122,7 +122,7 @@ def add_readings(
else:
daily_readings[date].append(reading)

dates = [x for x in daily_readings.keys()]
dates = [x for x in daily_readings]
self.days = dates

last_header = []
Expand Down Expand Up @@ -204,7 +204,7 @@ def add_dataframe(

channels = convert_to_channels(df)
channel_config = "".join(channels.keys())
for nmi_suffix in channels.keys():
for nmi_suffix in channels:
uom = uoms.get(nmi_suffix, "")
self.add_readings(
nmi=nmi,
Expand Down Expand Up @@ -234,8 +234,7 @@ def build_output(self) -> Generator[list, None, None]:
for nmi in sorted(self.meters):
suffixes = list(self.meters[nmi].keys())
for ch in sorted(suffixes):
for row in self.meters[nmi][ch]:
yield row
yield from self.meters[nmi][ch]
yield [900] # End of data row

def get_daily_rows(
Expand Down Expand Up @@ -343,10 +342,7 @@ def nem_filename(self) -> str:
end = self.days[-1]
nmis = list(self.meters.keys())
first_nmi = nmis[0]
if len(nmis) == 1:
uid = f"{first_nmi}_{start}_{end}"
else:
uid = f"{start}_{end}"
uid = f"{first_nmi}_{start}_{end}" if len(nmis) == 1 else f"{start}_{end}"
file_name = f"NEM12#{uid}#{self.from_participant}#{self.to_participant}"
return file_name

Expand Down
12 changes: 4 additions & 8 deletions nemwriter/nem13_writer.py
Expand Up @@ -12,7 +12,7 @@
from zipfile import ZIP_DEFLATED, ZipFile, ZipInfo


class NEM13(object):
class NEM13:
"""An NEM file object"""

def __init__(
Expand All @@ -33,7 +33,7 @@ def __init__(
self.meters = dict()

def __repr__(self):
return "<NEM13 Builder {} {}>".format(self.file_time, self.to_participant)
return f"<NEM13 Builder {self.file_time} {self.to_participant}>"

@property
def is_empty(self) -> bool:
Expand Down Expand Up @@ -106,8 +106,7 @@ def build_output(self) -> Generator[list, None, None]:
for nmi in self.meters:
for ch in self.meters[nmi]:
readings = self.meters[nmi][ch]
for reading in readings:
yield reading
yield from readings
yield [900] # End of data row

def nem_filename(self) -> str:
Expand All @@ -117,10 +116,7 @@ def nem_filename(self) -> str:
nmi_suffix = list(self.meters[first_nmi].keys())[0]
start = self.meters[first_nmi][nmi_suffix][0][9][0:8] # Previous read
end = self.meters[first_nmi][nmi_suffix][-1][14][0:8] # Current read
if len(nmis) > 1:
uid = f"{start}_{end}"
else:
uid = f"{first_nmi}_{start}_{end}"
uid = f"{start}_{end}" if len(nmis) > 1 else f"{first_nmi}_{start}_{end}"
file_name = f"NEM13#{uid}#{self.from_participant}#{self.to_participant}"
return file_name

Expand Down
2 changes: 1 addition & 1 deletion nemwriter/version.py
@@ -1 +1 @@
__version__ = "0.4.6"
__version__ = "0.5.0"
10 changes: 6 additions & 4 deletions pyproject.toml
Expand Up @@ -10,10 +10,10 @@ license = { file = "LICENSE" }
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.8",
"Operating System :: OS Independent",
]
keywords = ["energy", "NEM12", "NEM13"]
Expand All @@ -22,8 +22,7 @@ dynamic = ["version", "description"]
dependencies = ["pandas", "numpy"]

[project.optional-dependencies]
test = ["pytest >=2.7.3", "pytest-cov", "mypy", "nemreader"]
dev = ["black", "flake8", "flake8-bugbear", "pep8-naming", "flake8-builtins"]
test = ["ruff", "pytest >=2.7.3", "pytest-cov", "mypy", "nemreader"]

[project.urls]
Source = "https://github.com/aguinane/nem-writer/"
Expand All @@ -41,3 +40,6 @@ omit = ["*/version.py"]
show_missing = true
skip_empty = true
fail_under = 90

[tool.ruff.lint]
select = ["A", "B", "E", "F", "I", "N", "SIM", "UP"]
162 changes: 60 additions & 102 deletions requirements.txt
@@ -1,102 +1,60 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --all-extras --resolver=backtracking pyproject.toml
#
attrs==22.2.0
# via
# flake8-bugbear
# pytest
black==22.12.0
# via nemwriter (pyproject.toml)
click==8.1.3
# via
# black
# click-default-group-wheel
# sqlite-utils
# typer
click-default-group-wheel==1.2.2
# via sqlite-utils
coverage[toml]==7.0.5
# via pytest-cov
exceptiongroup==1.1.0
# via pytest
flake8==6.0.0
# via
# flake8-bugbear
# flake8-builtins
# nemwriter (pyproject.toml)
# pep8-naming
flake8-bugbear==23.1.14
# via nemwriter (pyproject.toml)
flake8-builtins==2.1.0
# via nemwriter (pyproject.toml)
iniconfig==2.0.0
# via pytest
mccabe==0.7.0
# via flake8
mypy==0.991
# via nemwriter (pyproject.toml)
mypy-extensions==0.4.3
# via
# black
# mypy
nemreader==0.7.2
# via nemwriter (pyproject.toml)
numpy==1.24.1
# via
# nemwriter (pyproject.toml)
# pandas
packaging==23.0
# via pytest
pandas==1.5.2
# via
# nemreader
# nemwriter (pyproject.toml)
pathspec==0.10.3
# via black
pep8-naming==0.13.3
# via nemwriter (pyproject.toml)
platformdirs==2.6.2
# via black
pluggy==1.0.0
# via pytest
pycodestyle==2.10.0
# via flake8
pydantic==1.10.4
# via nemreader
pyflakes==3.0.1
# via flake8
pytest==7.2.1
# via
# nemwriter (pyproject.toml)
# pytest-cov
pytest-cov==4.0.0
# via nemwriter (pyproject.toml)
python-dateutil==2.8.2
# via
# pandas
# sqlite-utils
pytz==2022.7.1
# via pandas
six==1.16.0
# via python-dateutil
sqlite-fts4==1.0.3
# via sqlite-utils
sqlite-utils==3.30
# via nemreader
tabulate==0.9.0
# via sqlite-utils
tomli==2.0.1
# via
# black
# coverage
# mypy
# pytest
typer==0.7.0
# via nemreader
typing-extensions==4.4.0
# via
# mypy
# pydantic
# This file was autogenerated by uv via the following command:
# uv pip compile pyproject.toml -o requirements.txt --all-extras
click==8.1.7
# via
# click-default-group
# sqlite-utils
# typer
click-default-group==1.2.4
# via sqlite-utils
coverage==7.4.4
# via pytest-cov
exceptiongroup==1.2.0
# via pytest
iniconfig==2.0.0
# via pytest
mypy==1.9.0
mypy-extensions==1.0.0
# via mypy
nemreader==0.8.8
numpy==1.26.4
# via pandas
packaging==24.0
# via pytest
pandas==2.2.1
# via nemreader
pluggy==1.4.0
# via
# pytest
# sqlite-utils
pytest==8.1.1
# via pytest-cov
pytest-cov==4.1.0
python-dateutil==2.9.0.post0
# via
# pandas
# sqlite-utils
pytz==2024.1
# via pandas
ruff==0.3.4
six==1.16.0
# via python-dateutil
sqlite-fts4==1.0.3
# via sqlite-utils
sqlite-utils==3.36
# via nemreader
tabulate==0.9.0
# via sqlite-utils
tomli==2.0.1
# via
# coverage
# mypy
# pytest
typer==0.9.0
# via nemreader
typing-extensions==4.10.0
# via
# mypy
# typer
tzdata==2024.1
# via pandas
4 changes: 1 addition & 3 deletions tests/test_example_nem12.py
Expand Up @@ -117,6 +117,4 @@ def test_importexport_nem12(example_file):
except ValueError:
clean_j = output[i][j]

assert clean_i == clean_j, "Row {i} Col {j} did not match".format(
i=i, j=j
)
assert clean_i == clean_j, f"Row {i} Col {j} did not match"
7 changes: 2 additions & 5 deletions tests/test_example_nem13.py
Expand Up @@ -47,10 +47,7 @@ def import_export_nem13(input_file):

def cleanse_val(val):
new_val = val
if val[-2:] == ".0":
new_val = val[:-2]
else:
new_val = val
new_val = val[:-2] if val[-2:] == ".0" else val
return new_val


Expand Down Expand Up @@ -81,4 +78,4 @@ def test_importexport_nem13(example_file):
if j not in [3, 5, 6, 10, 21, 22]:
assert cleanse_val(col) == cleanse_val(
output[i][j]
), "[{i},{j}] did not match".format(i=i, j=j)
), f"[{i},{j}] did not match"
3 changes: 2 additions & 1 deletion tests/test_nem12_writer.py
Expand Up @@ -6,7 +6,8 @@

def test_add_readings_adds_300_row_timestamps():
"""
update_datetime and msats_load_datetime should be added to the end of 300 rows if provided.
update_datetime and msats_load_datetime should be
added to the end of 300 rows if provided.
"""
# Create a NEM12 CSV with one 300 row of 30-minute reads.
nem12 = NEM12(to_participant="123")
Expand Down

0 comments on commit 4d13615

Please sign in to comment.