chellow 1726564344.0.0__py3-none-any.whl → 1726664509.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of chellow might be problematic. Click here for more details.
- chellow/e/bill_parsers/mm.py +1 -1
- chellow/e/hh_importer.py +4 -4
- chellow/e/hh_parser_df2.py +2 -1
- chellow/e/hh_parser_simple_csv.py +3 -1
- chellow/e/hh_parser_vital_xlsx.py +132 -0
- chellow/e/views.py +2 -2
- chellow/templates/e/dc_contract_hh_import.html +8 -7
- {chellow-1726564344.0.0.dist-info → chellow-1726664509.0.0.dist-info}/METADATA +1 -1
- {chellow-1726564344.0.0.dist-info → chellow-1726664509.0.0.dist-info}/RECORD +10 -9
- {chellow-1726564344.0.0.dist-info → chellow-1726664509.0.0.dist-info}/WHEEL +0 -0
chellow/e/bill_parsers/mm.py
CHANGED
|
@@ -217,7 +217,7 @@ def _handle_0860(headers, pre_record, record):
|
|
|
217
217
|
|
|
218
218
|
def _handle_1455(headers, pre_record, record):
|
|
219
219
|
parts = _chop_record(
|
|
220
|
-
record, ccl_kwh=13, unknown_1=
|
|
220
|
+
record, ccl_kwh=13, unknown_1=10, ccl_rate=13, ccl_gbp=12, unkown_2=8
|
|
221
221
|
)
|
|
222
222
|
bd = headers["breakdown"]
|
|
223
223
|
bd["ccl-kwh"] += Decimal(parts["ccl_kwh"])
|
chellow/e/hh_importer.py
CHANGED
|
@@ -8,7 +8,7 @@ import traceback
|
|
|
8
8
|
from collections import defaultdict, deque
|
|
9
9
|
from datetime import datetime as Datetime, timedelta as Timedelta
|
|
10
10
|
from decimal import Decimal
|
|
11
|
-
from io import StringIO
|
|
11
|
+
from io import StringIO
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
import jinja2
|
|
@@ -40,7 +40,7 @@ from chellow.utils import (
|
|
|
40
40
|
processes = defaultdict(list)
|
|
41
41
|
tasks = {}
|
|
42
42
|
|
|
43
|
-
extensions = [".df2", ".simple.csv", ".bg.csv"]
|
|
43
|
+
extensions = [".df2", ".simple.csv", ".bg.csv", ".vital.xlsx"]
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class HhDataImportProcess(threading.Thread):
|
|
@@ -277,7 +277,7 @@ class HhImportTask(threading.Thread):
|
|
|
277
277
|
self.log(f"File size is {fsize} bytes.")
|
|
278
278
|
self.log(f"Treating files as type {file_type}")
|
|
279
279
|
self.importer = HhDataImportProcess(
|
|
280
|
-
self.contract_id, 0,
|
|
280
|
+
self.contract_id, 0, f, fpath + file_type, fsize
|
|
281
281
|
)
|
|
282
282
|
|
|
283
283
|
self.importer.run()
|
|
@@ -412,7 +412,7 @@ class HhImportTask(threading.Thread):
|
|
|
412
412
|
self.log(f"File size is {fsize} bytes.")
|
|
413
413
|
self.log(f"Treating files as type {file_type}")
|
|
414
414
|
self.importer = HhDataImportProcess(
|
|
415
|
-
self.contract_id, 0,
|
|
415
|
+
self.contract_id, 0, f, fpath + file_type, fsize
|
|
416
416
|
)
|
|
417
417
|
|
|
418
418
|
self.importer.run()
|
chellow/e/hh_parser_df2.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import decimal
|
|
2
2
|
import itertools
|
|
3
|
+
from codecs import iterdecode
|
|
3
4
|
|
|
4
5
|
from werkzeug.exceptions import BadRequest
|
|
5
6
|
|
|
@@ -13,7 +14,7 @@ def create_parser(reader, mpan_map, messages):
|
|
|
13
14
|
class StarkDf2HhParser:
|
|
14
15
|
def __init__(self, reader, mpan_map, messages):
|
|
15
16
|
self.line = self.line_number = None
|
|
16
|
-
self.reader = zip(itertools.count(1), reader)
|
|
17
|
+
self.reader = zip(itertools.count(1), iterdecode(reader, "utf-8"))
|
|
17
18
|
|
|
18
19
|
self.line_number, self.line = next(self.reader)
|
|
19
20
|
if self.line.strip().upper() != "#F2":
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import csv
|
|
2
2
|
import itertools
|
|
3
|
+
from codecs import iterdecode
|
|
3
4
|
from datetime import datetime as Datetime
|
|
4
5
|
from decimal import Decimal
|
|
5
6
|
|
|
@@ -14,7 +15,8 @@ def create_parser(reader, mpan_map, messages):
|
|
|
14
15
|
|
|
15
16
|
class HhParserCsvSimple:
|
|
16
17
|
def __init__(self, reader, mpan_map, messages):
|
|
17
|
-
|
|
18
|
+
s = iterdecode(reader, "utf-8")
|
|
19
|
+
self.shredder = zip(itertools.count(1), csv.reader(s))
|
|
18
20
|
next(self.shredder) # skip the title line
|
|
19
21
|
self.values = None
|
|
20
22
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from datetime import datetime as Datetime
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal, InvalidOperation
|
|
4
|
+
from openpyxl import load_workbook
|
|
5
|
+
|
|
6
|
+
from werkzeug.exceptions import BadRequest
|
|
7
|
+
|
|
8
|
+
from chellow.utils import HH, ct_datetime, hh_before, hh_range, to_utc
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def create_parser(input_stream, mpan_map, messages):
|
|
12
|
+
return HhParserVital(input_stream, mpan_map, messages)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_cell(sheet, col, row):
|
|
16
|
+
try:
|
|
17
|
+
coordinates = f"{col}{row}"
|
|
18
|
+
return sheet[coordinates]
|
|
19
|
+
except IndexError:
|
|
20
|
+
raise BadRequest(f"Can't find the cell {coordinates} on sheet {sheet}.")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_date(sheet, col, row):
|
|
24
|
+
cell = get_cell(sheet, col, row)
|
|
25
|
+
val = cell.value
|
|
26
|
+
if not isinstance(val, Datetime):
|
|
27
|
+
raise BadRequest(
|
|
28
|
+
f"Problem reading {val} (of type {type(val)}) as a timestamp at "
|
|
29
|
+
f"{cell.coordinate}."
|
|
30
|
+
)
|
|
31
|
+
return val
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_str(sheet, col, row):
|
|
35
|
+
return get_cell(sheet, col, row).value.strip()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_dec(sheet, col, row):
|
|
39
|
+
return get_dec_from_cell(get_cell(sheet, col, row))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_dec_from_cell(cell):
|
|
43
|
+
try:
|
|
44
|
+
return Decimal(str(cell.value))
|
|
45
|
+
except InvalidOperation as e:
|
|
46
|
+
raise BadRequest(f"Problem parsing the number at {cell.coordinate}. {e}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_int(sheet, col, row):
|
|
50
|
+
return int(get_cell(sheet, col, row).value)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def find_hhs(sheet, imp_mpan, exp_mpan):
|
|
54
|
+
row = pres_readings = pres_ts = None
|
|
55
|
+
caches = {}
|
|
56
|
+
try:
|
|
57
|
+
for row in range(2, len(sheet["A"]) + 1):
|
|
58
|
+
imp_read_cell = get_cell(sheet, "H", row)
|
|
59
|
+
imp_read_val = imp_read_cell.value
|
|
60
|
+
if imp_read_val is None or imp_read_val == "":
|
|
61
|
+
break
|
|
62
|
+
|
|
63
|
+
exp_read_cell = get_cell(sheet, "I", row)
|
|
64
|
+
exp_read_val = exp_read_cell.value
|
|
65
|
+
if exp_read_val is None or exp_read_val == "":
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
# '16/09/2024 14:45:00
|
|
69
|
+
ts_str = get_str(sheet, "A", row)
|
|
70
|
+
ts_naive = Datetime.strptime(ts_str, "%d/%m/%Y %H:%M:%S")
|
|
71
|
+
ts_ct = ct_datetime(
|
|
72
|
+
ts_naive.year,
|
|
73
|
+
ts_naive.month,
|
|
74
|
+
ts_naive.day,
|
|
75
|
+
ts_naive.hour,
|
|
76
|
+
ts_naive.minute,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
imp_read = get_dec_from_cell(imp_read_cell)
|
|
80
|
+
exp_read = get_dec_from_cell(exp_read_cell)
|
|
81
|
+
ts = to_utc(ts_ct)
|
|
82
|
+
|
|
83
|
+
if ts_naive.minute in (0, 30) and hh_before(ts, pres_ts):
|
|
84
|
+
if pres_readings is not None:
|
|
85
|
+
pres_imp_read, pres_exp_read = pres_readings
|
|
86
|
+
hhs = hh_range(caches, ts, pres_ts - HH)
|
|
87
|
+
num_hhs = len(hhs)
|
|
88
|
+
val_imp = (pres_imp_read - imp_read) / num_hhs
|
|
89
|
+
val_exp = (pres_exp_read - exp_read) / num_hhs
|
|
90
|
+
for hh in hhs:
|
|
91
|
+
|
|
92
|
+
yield {
|
|
93
|
+
"mpan_core": imp_mpan,
|
|
94
|
+
"channel_type": "ACTIVE",
|
|
95
|
+
"start_date": hh,
|
|
96
|
+
"value": val_imp,
|
|
97
|
+
"status": "A",
|
|
98
|
+
}
|
|
99
|
+
yield {
|
|
100
|
+
"mpan_core": exp_mpan,
|
|
101
|
+
"channel_type": "ACTIVE",
|
|
102
|
+
"start_date": hh,
|
|
103
|
+
"value": val_exp,
|
|
104
|
+
"status": "A",
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pres_readings = imp_read, exp_read
|
|
108
|
+
pres_ts = ts
|
|
109
|
+
|
|
110
|
+
except BadRequest as e:
|
|
111
|
+
e.description = (f"Problem at row: {row}: {e.description}",)
|
|
112
|
+
raise e
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class HhParserVital:
|
|
116
|
+
def __init__(self, input_stream, mpan_map, messages):
|
|
117
|
+
book = load_workbook(input_stream, data_only=True)
|
|
118
|
+
sheet = book.worksheets[0]
|
|
119
|
+
imp_name = get_str(sheet, "H", 1).strip()
|
|
120
|
+
imp_mpan = mpan_map[imp_name]
|
|
121
|
+
exp_name = get_str(sheet, "I", 1).strip()
|
|
122
|
+
exp_mpan = mpan_map[exp_name]
|
|
123
|
+
self.data = iter(find_hhs(sheet, imp_mpan, exp_mpan))
|
|
124
|
+
|
|
125
|
+
def __iter__(self):
|
|
126
|
+
return self
|
|
127
|
+
|
|
128
|
+
def __next__(self):
|
|
129
|
+
return next(self.data)
|
|
130
|
+
|
|
131
|
+
def close(self):
|
|
132
|
+
pass
|
chellow/e/views.py
CHANGED
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
import threading
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from datetime import datetime as Datetime
|
|
6
|
-
from io import StringIO
|
|
6
|
+
from io import BytesIO, StringIO
|
|
7
7
|
from itertools import chain, islice
|
|
8
8
|
from random import random
|
|
9
9
|
|
|
@@ -1233,7 +1233,7 @@ def dc_contracts_hh_imports_post(contract_id):
|
|
|
1233
1233
|
contract = Contract.get_dc_by_id(g.sess, contract_id)
|
|
1234
1234
|
|
|
1235
1235
|
file_item = req_file("import_file")
|
|
1236
|
-
f =
|
|
1236
|
+
f = BytesIO(file_item.stream.read())
|
|
1237
1237
|
f.seek(0, os.SEEK_END)
|
|
1238
1238
|
file_size = f.tell()
|
|
1239
1239
|
f.seek(0)
|
|
@@ -21,15 +21,16 @@
|
|
|
21
21
|
Reached line number {{process.converter.line_number}}.
|
|
22
22
|
{% endif %}
|
|
23
23
|
</p>
|
|
24
|
-
{% elif process.
|
|
24
|
+
{% elif process.error is none %}
|
|
25
25
|
<p>The import has completed successfully.</p>
|
|
26
26
|
{% else %}
|
|
27
|
-
<p>The import failed
|
|
28
|
-
<ul>
|
|
29
|
-
{% for message in process.messages %}
|
|
30
|
-
<li>{{message}}</li>
|
|
31
|
-
{% endfor %}
|
|
32
|
-
</ul>
|
|
27
|
+
<p>The import failed. {{process.error}}</p>
|
|
33
28
|
{% endif %}
|
|
29
|
+
|
|
30
|
+
<ul>
|
|
31
|
+
{% for message in process.messages %}
|
|
32
|
+
<li>{{message}}</li>
|
|
33
|
+
{% endfor %}
|
|
34
|
+
</ul>
|
|
34
35
|
|
|
35
36
|
{% endblock %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1726664509.0.0
|
|
4
4
|
Summary: Web Application for checking UK energy bills.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WessexWater/chellow
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -24,10 +24,11 @@ chellow/e/dno_rate_parser.py,sha256=A5TP6KjyfT5lVWh7dX4SiXRi6wnf2lGv-H_T4Sod8CI,
|
|
|
24
24
|
chellow/e/duos.py,sha256=nwviRjz-qIt3GxIMHk0hItIT4dtKsxOWq9TUC1z-hO8,30864
|
|
25
25
|
chellow/e/elexon.py,sha256=ALhXS9Es7PV0z9ukPbIramn3cf3iLyFi-PMWPSm5iOs,5487
|
|
26
26
|
chellow/e/energy_management.py,sha256=aXC2qlGt3FAODlNl_frWzVYAQrJLP8FFOiNX3m-QE_Y,12388
|
|
27
|
-
chellow/e/hh_importer.py,sha256
|
|
27
|
+
chellow/e/hh_importer.py,sha256=vD2PRMSBhxmsyJ4xEq2N7Ib5Ohmf1FmQk8-APw8vBEs,21430
|
|
28
28
|
chellow/e/hh_parser_bg_csv.py,sha256=W5SU2MSpa8BGA0VJw1JXF-IwbCNLFy8fe35yxLZ7gEw,2453
|
|
29
|
-
chellow/e/hh_parser_df2.py,sha256=
|
|
30
|
-
chellow/e/hh_parser_simple_csv.py,sha256=
|
|
29
|
+
chellow/e/hh_parser_df2.py,sha256=tRAoVUUoJDlfPopm6usEBnhJz7dXMc2_KEWbkW9Gyq4,4330
|
|
30
|
+
chellow/e/hh_parser_simple_csv.py,sha256=lJx9tw9BWFSoBmns1Cws_vY-OIn90LPt2yvIN_CFcTE,2177
|
|
31
|
+
chellow/e/hh_parser_vital_xlsx.py,sha256=g9-CElfH1PPfwpuUcVvD6WQpBlNxCo8j9pq_0Yza0ZM,4125
|
|
31
32
|
chellow/e/laf_import.py,sha256=aqkcbjnvfBPszBLSNg6getP7iW1uWiTVHy6N5Z5x39U,5514
|
|
32
33
|
chellow/e/lcc.py,sha256=OkpynN8_iAdHRlu-yyU6BhRUqYYOZsUnl0HbHULYo_4,4670
|
|
33
34
|
chellow/e/mdd_importer.py,sha256=NugJr2JhuzkPTsEMl_5UdQuw5K2p8lVJ-hyz4MK6Hfg,35762
|
|
@@ -38,7 +39,7 @@ chellow/e/system_price.py,sha256=6w5J7bzwFAZubE2zdOFRiS8IIrVP8hkoIOaG2yCt-Ic,623
|
|
|
38
39
|
chellow/e/tlms.py,sha256=M33D6YpMixu2KkwSCzDRM3kThLgShg8exp63Obo75l8,8905
|
|
39
40
|
chellow/e/tnuos.py,sha256=XseYztPUsQXNKuBmystO2kzzwAG9ehCZgpGBTdgSk-A,4313
|
|
40
41
|
chellow/e/triad.py,sha256=lIQj7EdUrcFwEqleuHZXYU_bfzIwNOqUVVxB3NPQt4A,13710
|
|
41
|
-
chellow/e/views.py,sha256=
|
|
42
|
+
chellow/e/views.py,sha256=LG9KeYfXDkOvd7GrywuQPG1qDnpFvKe1oa95H0wRlqY,220618
|
|
42
43
|
chellow/e/bill_parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
44
|
chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=UgWXDPzQkQghyj_lfgBqoSJpHB-t-qOdSaB8qY6GLog,4071
|
|
44
45
|
chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=-HMoIfa_utXYKA44RuC0Xqv3vd2HLeQU_4P0iBUd3WA,4219
|
|
@@ -52,7 +53,7 @@ chellow/e/bill_parsers/gdf_csv.py,sha256=ZfK3Oc6oP28p_P9DIevLNB_zW2WLcEJ3Lvb1gL3
|
|
|
52
53
|
chellow/e/bill_parsers/haven_csv.py,sha256=0uENq8IgVNqdxfBQMBxLTSZWCOuDHXZC0xzk52SbfyE,13652
|
|
53
54
|
chellow/e/bill_parsers/haven_edi.py,sha256=YGPHRxPOhje9s32jqPHHELni2tooOYj3cMC_qaZVPq4,16107
|
|
54
55
|
chellow/e/bill_parsers/haven_edi_tprs.py,sha256=ZVX9CCqUybsot_Z0BEOJPvl9x5kSr7fEWyuJXvZDcz4,11841
|
|
55
|
-
chellow/e/bill_parsers/mm.py,sha256=
|
|
56
|
+
chellow/e/bill_parsers/mm.py,sha256=mXghmH_gLx82O20CUMBnUysAJqh-OMkR_-CGEcKrzhs,9544
|
|
56
57
|
chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py,sha256=yogXTuQHGRL7IiqvRWr2C9V24ez1j9Yx0128UygPE_k,4723
|
|
57
58
|
chellow/e/bill_parsers/settlement_dc_stark_xlsx.py,sha256=PlEqCZuJ9DfQXeeYQ64jtf3ML7sUt_tt61QOOTnkE5c,6380
|
|
58
59
|
chellow/e/bill_parsers/sse_edi.py,sha256=L85DOfNkqexeEIEr8pCBn_2sHJI-zEaw6cogpE3YyYM,15204
|
|
@@ -187,7 +188,7 @@ chellow/templates/e/dc_bill_import.html,sha256=NHjMSoFizvFQIaPWuVE3nTCtMDTzJB0Xm
|
|
|
187
188
|
chellow/templates/e/dc_bill_imports.html,sha256=lCaUR47r9KPr0VrQhEvVEaKexM5R_nmkxtzgpWZ0e9s,2135
|
|
188
189
|
chellow/templates/e/dc_contract.html,sha256=b6DLDrGdzN9Rri56pFvfpE7QZKYXGHib2veYAztuHlg,2352
|
|
189
190
|
chellow/templates/e/dc_contract_edit.html,sha256=IObmbHQmeZ_LSpnYgabmhoSNUR3aPmm-Jk5nJLM_u74,1706
|
|
190
|
-
chellow/templates/e/dc_contract_hh_import.html,sha256=
|
|
191
|
+
chellow/templates/e/dc_contract_hh_import.html,sha256=JncR3L6cOK4jghsGyr-itEqlIemXBXt3kL09wpqnQSE,856
|
|
191
192
|
chellow/templates/e/dc_contract_hh_imports.html,sha256=eXFDGyzSgag4JRism81_p5yTzQOjCIXaVkQ8tl3dDcM,8172
|
|
192
193
|
chellow/templates/e/dc_contract_properties.html,sha256=2EmA91gYWZcTOHQ3PxXQrpTOb8dm0OGjwRWsW6qNI9s,455
|
|
193
194
|
chellow/templates/e/dc_contract_properties_edit.html,sha256=TGYcHTlWbk5WmjZPkdbHhRVZcOpEfhowCp2penZcGiE,1704
|
|
@@ -365,6 +366,6 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
|
|
|
365
366
|
chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
|
|
366
367
|
chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
|
|
367
368
|
chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
|
|
368
|
-
chellow-
|
|
369
|
-
chellow-
|
|
370
|
-
chellow-
|
|
369
|
+
chellow-1726664509.0.0.dist-info/METADATA,sha256=PhQBcuYRWYyJltXJBei7Jl22-HKANq4qi5Nae4hRNhs,12204
|
|
370
|
+
chellow-1726664509.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
371
|
+
chellow-1726664509.0.0.dist-info/RECORD,,
|
|
File without changes
|