chellow 1706265605.0.0__py3-none-any.whl → 1706803240.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/elexon.py +11 -3
- chellow/e/rcrc.py +16 -17
- chellow/e/system_price.py +12 -21
- chellow/e/tlms.py +100 -80
- chellow/templates/macros.html +6 -5
- chellow/templates/non_core_contract_edit.html +2 -2
- chellow/views.py +1 -1
- {chellow-1706265605.0.0.dist-info → chellow-1706803240.0.0.dist-info}/METADATA +2 -1
- {chellow-1706265605.0.0.dist-info → chellow-1706803240.0.0.dist-info}/RECORD +10 -10
- {chellow-1706265605.0.0.dist-info → chellow-1706803240.0.0.dist-info}/WHEEL +0 -0
chellow/e/elexon.py
CHANGED
|
@@ -57,16 +57,17 @@ def api_search(s, resource_id, sort=None):
|
|
|
57
57
|
return res_j
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def run_import(sess, log, set_progress):
|
|
60
|
+
def run_import(sess, log, set_progress, scripting_key):
|
|
61
61
|
log("Starting to import data from Elexon")
|
|
62
62
|
s = requests.Session()
|
|
63
63
|
s.verify = False
|
|
64
64
|
|
|
65
65
|
for mod_name in ("chellow.e.system_price", "chellow.e.tlms", "chellow.e.rcrc"):
|
|
66
66
|
mod = import_module(mod_name)
|
|
67
|
-
mod.elexon_import(sess, log, set_progress, s)
|
|
67
|
+
mod.elexon_import(sess, log, set_progress, s, scripting_key)
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
ELEXON_PORTAL_SCRIPTING_KEY_KEY = "elexonportal_scripting_key"
|
|
70
71
|
LAST_RUN_KEY = "last_run"
|
|
71
72
|
GLOBAL_ALERT = "There's a problem with an <a href='/e/elexon'>Elexon import</a>."
|
|
72
73
|
ELEXON_STATE_KEY = "elexon"
|
|
@@ -119,6 +120,13 @@ class Elexon(threading.Thread):
|
|
|
119
120
|
with Session() as sess:
|
|
120
121
|
try:
|
|
121
122
|
config = Contract.get_non_core_by_name(sess, "configuration")
|
|
123
|
+
props = config.make_properties()
|
|
124
|
+
scripting_key = props.get(ELEXON_PORTAL_SCRIPTING_KEY_KEY)
|
|
125
|
+
if scripting_key is None:
|
|
126
|
+
raise BadRequest(
|
|
127
|
+
f"The property {ELEXON_PORTAL_SCRIPTING_KEY_KEY} "
|
|
128
|
+
f"cannot be found in the configuration properties."
|
|
129
|
+
)
|
|
122
130
|
state = config.make_state()
|
|
123
131
|
try:
|
|
124
132
|
elexon_state = state[ELEXON_STATE_KEY]
|
|
@@ -128,7 +136,7 @@ class Elexon(threading.Thread):
|
|
|
128
136
|
elexon_state[LAST_RUN_KEY] = utc_datetime_now()
|
|
129
137
|
config.update_state(state)
|
|
130
138
|
sess.commit()
|
|
131
|
-
run_import(sess, self.log, self.set_progress)
|
|
139
|
+
run_import(sess, self.log, self.set_progress, scripting_key)
|
|
132
140
|
except BaseException as e:
|
|
133
141
|
msg = f"{e.description} " if isinstance(e, BadRequest) else ""
|
|
134
142
|
self.log(f"{msg}{traceback.format_exc()}")
|
chellow/e/rcrc.py
CHANGED
|
@@ -63,14 +63,23 @@ def _find_month(lines, month_start, month_finish):
|
|
|
63
63
|
next(parser)
|
|
64
64
|
month_rcrcs = {}
|
|
65
65
|
for values in parser:
|
|
66
|
-
|
|
66
|
+
if len(values) == 0:
|
|
67
|
+
continue
|
|
68
|
+
date_str = values[0]
|
|
69
|
+
if "/" in date_str:
|
|
70
|
+
pattern = "%d/%m/%Y"
|
|
71
|
+
elif " " in date_str:
|
|
72
|
+
pattern = "%d %b %Y"
|
|
73
|
+
else:
|
|
74
|
+
raise BadRequest(f"Date format {date_str} not recognized.")
|
|
75
|
+
hh_date = to_utc(ct_datetime_parse(date_str, pattern))
|
|
67
76
|
hh_date += relativedelta(minutes=30 * int(values[2]))
|
|
68
77
|
if month_start <= hh_date <= month_finish:
|
|
69
78
|
month_rcrcs[key_format(hh_date)] = Decimal(values[3])
|
|
70
79
|
return month_rcrcs
|
|
71
80
|
|
|
72
81
|
|
|
73
|
-
def elexon_import(sess, log, set_progress, s):
|
|
82
|
+
def elexon_import(sess, log, set_progress, s, scripting_key):
|
|
74
83
|
log("Starting to check RCRCs.")
|
|
75
84
|
contract = Contract.get_non_core_by_name(sess, "rcrc")
|
|
76
85
|
latest_rs = (
|
|
@@ -90,25 +99,15 @@ def elexon_import(sess, log, set_progress, s):
|
|
|
90
99
|
month_start, month_finish = months[1]
|
|
91
100
|
now = utc_datetime_now()
|
|
92
101
|
if now > month_finish:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
scripting_key = props.get(ELEXON_PORTAL_SCRIPTING_KEY_KEY)
|
|
97
|
-
if scripting_key is None:
|
|
98
|
-
raise BadRequest(
|
|
99
|
-
f"The property {ELEXON_PORTAL_SCRIPTING_KEY_KEY} cannot be found in "
|
|
100
|
-
f"the configuration properties."
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
contract_props = contract.make_properties()
|
|
104
|
-
url_str = f"{contract_props['url']}file/download/RCRC_FILE?key={scripting_key}"
|
|
102
|
+
params = {"key": scripting_key}
|
|
103
|
+
url_str = "https://downloads.elexonportal.co.uk/file/download/RCRC_FILE"
|
|
105
104
|
log(
|
|
106
|
-
f"Downloading {url_str} to see if data is available
|
|
107
|
-
f"{hh_format(month_start)} to {hh_format(month_finish)}."
|
|
105
|
+
f"Downloading {url_str}?key={scripting_key} to see if data is available "
|
|
106
|
+
f"from {hh_format(month_start)} to {hh_format(month_finish)}."
|
|
108
107
|
)
|
|
109
108
|
|
|
110
109
|
sess.rollback() # Avoid long-running transaction
|
|
111
|
-
r = s.get(url_str, timeout=
|
|
110
|
+
r = s.get(url_str, timeout=120, params=params)
|
|
112
111
|
month_rcrcs = _find_month(
|
|
113
112
|
(x.decode() for x in r.iter_lines()), month_start, month_finish
|
|
114
113
|
)
|
chellow/e/system_price.py
CHANGED
|
@@ -2,6 +2,8 @@ import datetime
|
|
|
2
2
|
import traceback
|
|
3
3
|
from datetime import timedelta as Timedelta
|
|
4
4
|
|
|
5
|
+
from sqlalchemy import select
|
|
6
|
+
|
|
5
7
|
from werkzeug.exceptions import BadRequest
|
|
6
8
|
|
|
7
9
|
import xlrd
|
|
@@ -12,9 +14,6 @@ from chellow.models import Contract, RateScript
|
|
|
12
14
|
from chellow.utils import HH, hh_format, to_ct, to_utc
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
ELEXON_PORTAL_SCRIPTING_KEY_KEY = "elexonportal_scripting_key"
|
|
16
|
-
|
|
17
|
-
|
|
18
17
|
def key_format(dt):
|
|
19
18
|
return dt.strftime("%d %H:%M")
|
|
20
19
|
|
|
@@ -61,7 +60,7 @@ def hh(data_source):
|
|
|
61
60
|
h["ssp-gbp"] = h["nbp-kwh"] * ssp
|
|
62
61
|
|
|
63
62
|
|
|
64
|
-
def elexon_import(sess, log, set_progress, s):
|
|
63
|
+
def elexon_import(sess, log, set_progress, s, scripting_key):
|
|
65
64
|
contract = Contract.get_non_core_by_name(sess, "system_price")
|
|
66
65
|
contract_props = contract.make_properties()
|
|
67
66
|
|
|
@@ -74,9 +73,9 @@ def elexon_import(sess, log, set_progress, s):
|
|
|
74
73
|
|
|
75
74
|
log("Starting to check System Prices.")
|
|
76
75
|
|
|
77
|
-
for rscript in (
|
|
78
|
-
|
|
79
|
-
.
|
|
76
|
+
for rscript in sess.scalars(
|
|
77
|
+
select(RateScript)
|
|
78
|
+
.where(RateScript.contract == contract)
|
|
80
79
|
.order_by(RateScript.start_date.desc())
|
|
81
80
|
):
|
|
82
81
|
ns = loads(rscript.script)
|
|
@@ -87,24 +86,16 @@ def elexon_import(sess, log, set_progress, s):
|
|
|
87
86
|
elif rates[key_format(rscript.finish_date)]["run"] == "DF":
|
|
88
87
|
fill_start = rscript.finish_date + HH
|
|
89
88
|
break
|
|
89
|
+
params = {"key": scripting_key}
|
|
90
|
+
url = "https://downloads.elexonportal.co.uk/file/download/BESTVIEWPRICES_FILE"
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
scripting_key = config_props.get(ELEXON_PORTAL_SCRIPTING_KEY_KEY)
|
|
95
|
-
if scripting_key is None:
|
|
96
|
-
raise BadRequest(
|
|
97
|
-
f"The property {ELEXON_PORTAL_SCRIPTING_KEY_KEY} cannot be found in "
|
|
98
|
-
f"the configuration properties."
|
|
99
|
-
)
|
|
100
|
-
url = (
|
|
101
|
-
f"{contract_props['url']}file/download/BESTVIEWPRICES_FILE?key={scripting_key}"
|
|
92
|
+
log(
|
|
93
|
+
f"Downloading from {url}?key={scripting_key} and extracting data from "
|
|
94
|
+
f"{hh_format(fill_start)}"
|
|
102
95
|
)
|
|
103
96
|
|
|
104
|
-
log(f"Downloading from {url} and extracting data from {hh_format(fill_start)}")
|
|
105
|
-
|
|
106
97
|
sess.rollback() # Avoid long-running transactions
|
|
107
|
-
res = s.get(url)
|
|
98
|
+
res = s.get(url, params=params)
|
|
108
99
|
log(f"Received {res.status_code} {res.reason}")
|
|
109
100
|
data = res.content
|
|
110
101
|
book = xlrd.open_workbook(file_contents=data)
|
chellow/e/tlms.py
CHANGED
|
@@ -4,7 +4,7 @@ from decimal import Decimal, InvalidOperation
|
|
|
4
4
|
|
|
5
5
|
from dateutil.relativedelta import relativedelta
|
|
6
6
|
|
|
7
|
-
from sqlalchemy import or_
|
|
7
|
+
from sqlalchemy import or_, select
|
|
8
8
|
from sqlalchemy.sql.expression import null
|
|
9
9
|
|
|
10
10
|
from werkzeug.exceptions import BadRequest
|
|
@@ -12,11 +12,9 @@ from werkzeug.exceptions import BadRequest
|
|
|
12
12
|
from zish import dumps, loads
|
|
13
13
|
|
|
14
14
|
from chellow.models import Contract, RateScript
|
|
15
|
-
from chellow.utils import HH, hh_format, to_ct, to_utc
|
|
15
|
+
from chellow.utils import HH, hh_format, hh_range, to_ct, to_utc
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
ELEXON_PORTAL_SCRIPTING_KEY_KEY = "elexonportal_scripting_key"
|
|
19
|
-
|
|
20
18
|
RUNS = ["DF", "RF", "R3", "R2", "R1", "SF", "II"]
|
|
21
19
|
|
|
22
20
|
|
|
@@ -77,51 +75,76 @@ def hh(data_source, run="DF"):
|
|
|
77
75
|
h["nbp-kwh"] = h["gsp-kwh"] * tlm
|
|
78
76
|
|
|
79
77
|
|
|
80
|
-
def
|
|
81
|
-
for
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
def _find_complete_date(caches, sess, contract, cache):
|
|
79
|
+
for rs in sess.scalars(
|
|
80
|
+
select(RateScript)
|
|
81
|
+
.where(RateScript.contract == contract, RateScript.finish_date != null())
|
|
82
|
+
.order_by(RateScript.start_date.desc())
|
|
83
|
+
):
|
|
84
|
+
rates = rs.make_script()
|
|
85
|
+
rates["id"] = rs.id
|
|
86
|
+
cache["rate_scripts"].append(rates)
|
|
87
|
+
timestamps = cache["timestamps"]
|
|
88
|
+
tlms = rates["tlms"]
|
|
89
|
+
complete = True
|
|
90
|
+
for dt in hh_range(caches, rs.start_date, rs.finish_date):
|
|
91
|
+
timestamps[dt] = rates
|
|
92
|
+
key = key_format(dt)
|
|
93
|
+
if key in tlms:
|
|
94
|
+
gps = tlms[key]
|
|
95
|
+
for group in GSP_GROUP_LOOKUP.values():
|
|
96
|
+
if not (group in gps and "DF" in gps[group]):
|
|
97
|
+
complete = False
|
|
98
|
+
else:
|
|
99
|
+
complete = False
|
|
100
|
+
|
|
101
|
+
if complete:
|
|
102
|
+
return rs.finish_date
|
|
86
103
|
|
|
87
104
|
|
|
88
|
-
def elexon_import(sess, log, set_progress, s):
|
|
89
|
-
cache = {}
|
|
105
|
+
def elexon_import(sess, log, set_progress, s, scripting_key):
|
|
106
|
+
cache = {"rate_scripts": [], "timestamps": {}}
|
|
107
|
+
caches = {}
|
|
90
108
|
log("Starting to check TLMs.")
|
|
91
109
|
contract = Contract.get_non_core_by_name(sess, "tlms")
|
|
92
110
|
contract_props = contract.make_properties()
|
|
93
111
|
if contract_props.get("enabled", False):
|
|
94
|
-
config = Contract.get_non_core_by_name(sess, "configuration")
|
|
95
|
-
props = config.make_properties()
|
|
96
|
-
scripting_key = props.get(ELEXON_PORTAL_SCRIPTING_KEY_KEY)
|
|
97
|
-
if scripting_key is None:
|
|
98
|
-
raise BadRequest(
|
|
99
|
-
f"The property {ELEXON_PORTAL_SCRIPTING_KEY_KEY} cannot be "
|
|
100
|
-
f"found in the configuration properties."
|
|
101
|
-
)
|
|
102
112
|
|
|
103
|
-
|
|
113
|
+
params = {"key": scripting_key}
|
|
114
|
+
url_str = "https://downloads.elexonportal.co.uk/file/download/TLM_FILE"
|
|
115
|
+
complete_date = _find_complete_date(caches, sess, contract, cache)
|
|
116
|
+
log(f"Found complete up to {complete_date}")
|
|
104
117
|
|
|
105
118
|
sess.rollback() # Avoid long-running transaction
|
|
106
|
-
r = s.get(url_str)
|
|
119
|
+
r = s.get(url_str, params=params, timeout=120)
|
|
107
120
|
parser = csv.reader(
|
|
108
121
|
(x.decode() for x in r.iter_lines()), delimiter=",", quotechar='"'
|
|
109
122
|
)
|
|
110
|
-
log(f"Opened {url_str}.")
|
|
123
|
+
log(f"Opened {url_str}?key={scripting_key}.")
|
|
111
124
|
|
|
112
125
|
next(parser, None)
|
|
113
126
|
for values in parser:
|
|
114
127
|
if len(values) == 0:
|
|
115
128
|
continue
|
|
116
129
|
|
|
117
|
-
|
|
130
|
+
set_progress(values[0])
|
|
131
|
+
|
|
132
|
+
if values[3] == "":
|
|
118
133
|
for zone in GSP_GROUP_LOOKUP.keys():
|
|
119
134
|
values[3] = zone
|
|
120
|
-
_process_line(
|
|
135
|
+
_process_line(
|
|
136
|
+
cache, sess, contract, log, values, complete_date, caches
|
|
137
|
+
)
|
|
121
138
|
else:
|
|
122
|
-
_process_line(cache, sess, contract, log, values)
|
|
139
|
+
_process_line(cache, sess, contract, log, values, complete_date, caches)
|
|
140
|
+
|
|
141
|
+
for rscript in cache["rate_scripts"]:
|
|
142
|
+
rs = sess.scalars(
|
|
143
|
+
select(RateScript).where(RateScript.id == rscript["id"])
|
|
144
|
+
).one()
|
|
145
|
+
rs.script = dumps({"tlms": rscript["tlms"]})
|
|
146
|
+
sess.commit()
|
|
123
147
|
|
|
124
|
-
_save_cache(sess, cache)
|
|
125
148
|
else:
|
|
126
149
|
log(
|
|
127
150
|
"The importer is disabled. Set 'enabled' to 'true' in the "
|
|
@@ -148,10 +171,12 @@ GSP_GROUP_LOOKUP = {
|
|
|
148
171
|
}
|
|
149
172
|
|
|
150
173
|
|
|
151
|
-
def _process_line(cache, sess, contract, log_func, values):
|
|
174
|
+
def _process_line(cache, sess, contract, log_func, values, complete_date, caches):
|
|
152
175
|
hh_date_ct = to_ct(Datetime.strptime(values[0], "%d/%m/%Y"))
|
|
153
176
|
hh_date = to_utc(hh_date_ct)
|
|
154
177
|
hh_date += relativedelta(minutes=30 * (int(values[2]) - 1))
|
|
178
|
+
if complete_date is not None and hh_date <= complete_date:
|
|
179
|
+
return
|
|
155
180
|
run = values[1]
|
|
156
181
|
gsp_group_code = GSP_GROUP_LOOKUP[values[3]]
|
|
157
182
|
off_taking_str = values[4]
|
|
@@ -166,45 +191,13 @@ def _process_line(cache, sess, contract, log_func, values):
|
|
|
166
191
|
|
|
167
192
|
delivering = Decimal(values[5])
|
|
168
193
|
|
|
194
|
+
key = key_format(hh_date)
|
|
169
195
|
try:
|
|
170
|
-
|
|
196
|
+
cache["timestamps"][hh_date]["tlms"][key][gsp_group_code][run]
|
|
171
197
|
except KeyError:
|
|
172
|
-
_save_cache(sess, cache)
|
|
173
198
|
try:
|
|
174
|
-
|
|
199
|
+
rate = cache["timestamps"][hh_date]
|
|
175
200
|
except KeyError:
|
|
176
|
-
yr_cache = cache[hh_date.year] = {}
|
|
177
|
-
|
|
178
|
-
rs = (
|
|
179
|
-
sess.query(RateScript)
|
|
180
|
-
.filter(
|
|
181
|
-
RateScript.contract == contract,
|
|
182
|
-
RateScript.start_date <= hh_date,
|
|
183
|
-
or_(
|
|
184
|
-
RateScript.finish_date == null(), RateScript.finish_date >= hh_date
|
|
185
|
-
),
|
|
186
|
-
)
|
|
187
|
-
.first()
|
|
188
|
-
)
|
|
189
|
-
while rs is None:
|
|
190
|
-
log_func(f"There's no rate script at {hh_format(hh_date)}.")
|
|
191
|
-
latest_rs = (
|
|
192
|
-
sess.query(RateScript)
|
|
193
|
-
.filter(RateScript.contract == contract)
|
|
194
|
-
.order_by(RateScript.start_date.desc())
|
|
195
|
-
.first()
|
|
196
|
-
)
|
|
197
|
-
contract.update_rate_script(
|
|
198
|
-
sess,
|
|
199
|
-
latest_rs,
|
|
200
|
-
latest_rs.start_date,
|
|
201
|
-
latest_rs.start_date + relativedelta(months=2) - HH,
|
|
202
|
-
loads(latest_rs.script),
|
|
203
|
-
)
|
|
204
|
-
new_rs_start = latest_rs.start_date + relativedelta(months=1)
|
|
205
|
-
contract.insert_rate_script(sess, new_rs_start, {})
|
|
206
|
-
sess.commit()
|
|
207
|
-
log_func(f"Added a rate script starting at {hh_format(new_rs_start)}.")
|
|
208
201
|
|
|
209
202
|
rs = (
|
|
210
203
|
sess.query(RateScript)
|
|
@@ -218,29 +211,56 @@ def _process_line(cache, sess, contract, log_func, values):
|
|
|
218
211
|
)
|
|
219
212
|
.first()
|
|
220
213
|
)
|
|
214
|
+
assert rs is None
|
|
215
|
+
while rs is None:
|
|
216
|
+
log_func(f"There's no rate script at {hh_format(hh_date)}.")
|
|
217
|
+
latest_rs = (
|
|
218
|
+
sess.query(RateScript)
|
|
219
|
+
.filter(RateScript.contract == contract)
|
|
220
|
+
.order_by(RateScript.start_date.desc())
|
|
221
|
+
.first()
|
|
222
|
+
)
|
|
223
|
+
contract.update_rate_script(
|
|
224
|
+
sess,
|
|
225
|
+
latest_rs,
|
|
226
|
+
latest_rs.start_date,
|
|
227
|
+
latest_rs.start_date + relativedelta(months=2) - HH,
|
|
228
|
+
loads(latest_rs.script),
|
|
229
|
+
)
|
|
230
|
+
new_rs_start = latest_rs.start_date + relativedelta(months=1)
|
|
231
|
+
new_rs = contract.insert_rate_script(sess, new_rs_start, {})
|
|
232
|
+
rt = {"tlms": {}, "id": new_rs.id}
|
|
233
|
+
cache["rate_scripts"].append(rt)
|
|
234
|
+
for h in hh_range(caches, new_rs.start_date, new_rs.finish_date):
|
|
235
|
+
cache["timestamps"][h] = rt
|
|
236
|
+
sess.commit()
|
|
237
|
+
log_func(f"Added a rate script starting at {hh_format(new_rs_start)}.")
|
|
238
|
+
|
|
239
|
+
rs = (
|
|
240
|
+
sess.query(RateScript)
|
|
241
|
+
.filter(
|
|
242
|
+
RateScript.contract == contract,
|
|
243
|
+
RateScript.start_date <= hh_date,
|
|
244
|
+
or_(
|
|
245
|
+
RateScript.finish_date == null(),
|
|
246
|
+
RateScript.finish_date >= hh_date,
|
|
247
|
+
),
|
|
248
|
+
)
|
|
249
|
+
.first()
|
|
250
|
+
)
|
|
221
251
|
|
|
222
|
-
|
|
252
|
+
rate = cache["timestamps"][hh_date]
|
|
223
253
|
|
|
224
254
|
try:
|
|
225
|
-
|
|
255
|
+
existing = rate["tlms"][key]
|
|
226
256
|
except KeyError:
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
yr_cache[hh_date.month] = rs, rates, rts
|
|
230
|
-
sess.rollback()
|
|
231
|
-
|
|
232
|
-
key = key_format(hh_date)
|
|
233
|
-
try:
|
|
234
|
-
existing = rts[key]
|
|
235
|
-
except KeyError:
|
|
236
|
-
existing = rts[key] = {}
|
|
257
|
+
existing = rate["tlms"][key] = {}
|
|
237
258
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
259
|
+
try:
|
|
260
|
+
group = existing[gsp_group_code]
|
|
261
|
+
except KeyError:
|
|
262
|
+
group = existing[gsp_group_code] = {}
|
|
242
263
|
|
|
243
|
-
if run not in group:
|
|
244
264
|
group[run] = {"off_taking": off_taking, "delivering": delivering}
|
|
245
265
|
|
|
246
266
|
log_func(
|
chellow/templates/macros.html
CHANGED
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
<input type="hidden" name="resolution" value="{{resolution}}">
|
|
14
14
|
|
|
15
15
|
{% if initial %}
|
|
16
|
-
{
|
|
17
|
-
{{input_hidden(
|
|
18
|
-
{{input_hidden(
|
|
19
|
-
{{input_hidden(
|
|
20
|
-
{{input_hidden(
|
|
16
|
+
{% set initial_ct = initial|to_ct %}
|
|
17
|
+
{{input_hidden(year_name, initial=initial_ct.year)}}
|
|
18
|
+
{{input_hidden(month_name, initial=initial_ct.month)}}
|
|
19
|
+
{{input_hidden(day_name, initial=initial_ct.day)}}
|
|
20
|
+
{{input_hidden(hour_name, initial=initial_ct.hour)}}
|
|
21
|
+
{{input_hidden(minute_name, initial=initial_ct.minute)}}
|
|
21
22
|
{% else %}
|
|
22
23
|
{{input_hidden(year_name, initial=None)}}
|
|
23
24
|
{{input_hidden(month_name, initial=None)}}
|
|
@@ -68,8 +68,8 @@ to the 'urls' list. */
|
|
|
68
68
|
{% elif contract.name == 'tlms' %}
|
|
69
69
|
<h4>Example</h4>
|
|
70
70
|
<pre>{
|
|
71
|
-
"enabled": true,
|
|
72
|
-
|
|
71
|
+
"enabled": true,
|
|
72
|
+
}
|
|
73
73
|
|
|
74
74
|
/* Requires the 'elexonportal_scripting_key' to be set in the 'configuration'
|
|
75
75
|
non-core contract */
|
chellow/views.py
CHANGED
|
@@ -2459,7 +2459,7 @@ def input_date_get():
|
|
|
2459
2459
|
|
|
2460
2460
|
month_max_day = (ct_datetime(year, month, 1) + relativedelta(months=1) - HH).day
|
|
2461
2461
|
|
|
2462
|
-
initial = ct_datetime(year, month, min(day, month_max_day), hour, minute)
|
|
2462
|
+
initial = to_utc(ct_datetime(year, month, min(day, month_max_day), hour, minute))
|
|
2463
2463
|
|
|
2464
2464
|
return render_template(
|
|
2465
2465
|
"input_date.html",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1706803240.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)
|
|
@@ -55,6 +55,7 @@ Chellow is a Python web application that uses the PostgreSQL database. To instal
|
|
|
55
55
|
Chellow, follow these steps:
|
|
56
56
|
|
|
57
57
|
* Install [PostgreSQL](http://www.postgresql.org/) 12
|
|
58
|
+
* Set the PostgreSQL time zone to 'UTC'.
|
|
58
59
|
* Create a PostgreSQL database: `createdb --encoding=UTF8 chellow`
|
|
59
60
|
* Set up the following environment variables to configure Chellow:
|
|
60
61
|
|
|
@@ -11,7 +11,7 @@ chellow/proxy.py,sha256=cVXIktPlX3tQ1BYcwxq0nJXKE6r3DtFTtfFHPq55HaM,1351
|
|
|
11
11
|
chellow/rate_server.py,sha256=XFcyKgo2r7GBybm6TRLBaBRqDpgk4vmhqgRoM3nflXM,5626
|
|
12
12
|
chellow/testing.py,sha256=Od4HHH6pZrhJ_De118_F55RJEKmAvhUH2S24QE9qFQk,3635
|
|
13
13
|
chellow/utils.py,sha256=32qPWEGzCPKPhSM7ztpzcR6ZG74sVZanScDIdK50Rq4,19308
|
|
14
|
-
chellow/views.py,sha256=
|
|
14
|
+
chellow/views.py,sha256=_vkjpoprfhIAzbaDlBYf2ewfsJXcthY_t9tfjrcMK9g,78520
|
|
15
15
|
chellow/e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
chellow/e/aahedc.py,sha256=d2usudp7KYWpU6Pk3fal5EQ47EbvkvKeaFGylnb3NWw,606
|
|
17
17
|
chellow/e/bill_importer.py,sha256=y1bpn49xDwltj0PRFowWsjAVamcD8eyxUbCTdGxEZiE,7389
|
|
@@ -22,7 +22,7 @@ chellow/e/cfd.py,sha256=3yRchycC-WZwgqryGQK3B59OcMGVIWgbxrkekUOy-9k,14914
|
|
|
22
22
|
chellow/e/computer.py,sha256=J8VvYjcSeJNrG2Ak8Zi2t2bb_8tMrkHWny4JQlgIyy8,67032
|
|
23
23
|
chellow/e/dno_rate_parser.py,sha256=5MYEbcYngh7n6Szn2h9zLTwQKXH-WHKy6c80PYwNLLQ,20983
|
|
24
24
|
chellow/e/duos.py,sha256=ISTcNqe9KNjVNM2Qs8IBoQxnmSXOt5W_G7tZxp4T78M,28870
|
|
25
|
-
chellow/e/elexon.py,sha256=
|
|
25
|
+
chellow/e/elexon.py,sha256=s8QdLUQMeylLhghxvvhLyOL3-0ifUnMfmo3vcbot_DY,5487
|
|
26
26
|
chellow/e/energy_management.py,sha256=aXC2qlGt3FAODlNl_frWzVYAQrJLP8FFOiNX3m-QE_Y,12388
|
|
27
27
|
chellow/e/hh_importer.py,sha256=G1CK3AQQuJaNXCxGEY3UU_CjqOzfVZT-PDR67b3zpA0,20362
|
|
28
28
|
chellow/e/hh_parser_bg_csv.py,sha256=IOjM-QliKzvSXyhslmxz504XWnsGkVKEaCQ48SNeNeQ,2423
|
|
@@ -31,11 +31,11 @@ chellow/e/hh_parser_simple_csv.py,sha256=lVRprIEjDpTQdeXm2xcLmRAyre2LWec8ueVwcCI
|
|
|
31
31
|
chellow/e/laf_import.py,sha256=aqkcbjnvfBPszBLSNg6getP7iW1uWiTVHy6N5Z5x39U,5514
|
|
32
32
|
chellow/e/lcc.py,sha256=q5iGbeYZdnozkIdbGuxXoJO-1KDO7AHqYOXEGBIaNHI,4963
|
|
33
33
|
chellow/e/mdd_importer.py,sha256=9GN-at0DC3vOjd-0N2U856O3hInnjkMWWcRfxzQ5DjA,32042
|
|
34
|
-
chellow/e/rcrc.py,sha256=
|
|
34
|
+
chellow/e/rcrc.py,sha256=92CA1uIotIHd1epQ_jEPdJKzXqDFV-AoJOJeRO6MEyA,4274
|
|
35
35
|
chellow/e/ro.py,sha256=dZKZv_9wXSWuwcb3jiKavoD_9ot-PZseNVeEEe0siLo,596
|
|
36
36
|
chellow/e/scenario.py,sha256=1tUxnvwTzr6cKqiw2wphdv5XDzV6JO6UVYkyQa67vHs,23263
|
|
37
|
-
chellow/e/system_price.py,sha256=
|
|
38
|
-
chellow/e/tlms.py,sha256=
|
|
37
|
+
chellow/e/system_price.py,sha256=3cPWohHmmBI9v7fENLBzXQkpAeC3r0s5xV29Nmr6k_E,5839
|
|
38
|
+
chellow/e/tlms.py,sha256=kHAy2A2d1Mma7x4GdNDyrzscJd5DpJtDBYiZEg241Dw,8538
|
|
39
39
|
chellow/e/tnuos.py,sha256=qybrPCVukQ2l0RIdqn8XtHEbAU0izGoqUrFLoLVUoVI,4126
|
|
40
40
|
chellow/e/triad.py,sha256=S6LEMHvUKhAZe0-yfLIRciYDZ8IKMn1jh1TmmsbQD3s,13588
|
|
41
41
|
chellow/e/views.py,sha256=aZecpfM1sVn3xMwlKuiw9pE2f6s4uyd98obQXToKtqA,212466
|
|
@@ -121,11 +121,11 @@ chellow/templates/home.html,sha256=_ANKmcnlk_PDyZl6SCmejU8d90f3t8EH_rDDPDyYUwE,5
|
|
|
121
121
|
chellow/templates/input_date.html,sha256=rpgB5n0LfN8Y5djN_ZiuSxqdskxzCoKrEqI7hyJkVQo,1248
|
|
122
122
|
chellow/templates/local_report.html,sha256=pV7_0QwyQ-D3OS9LXrly5pq3qprZnwTCoq6vCnMTkS4,1332
|
|
123
123
|
chellow/templates/local_reports.html,sha256=4wbfVkY4wUfSSfWjxqIsvCpIsa9k7H_dGAjznrG5jNM,701
|
|
124
|
-
chellow/templates/macros.html,sha256=
|
|
124
|
+
chellow/templates/macros.html,sha256=9sGRgLxLmhYTIstfL3MgUDFIoRV89SlwPHmuvMqh-UI,5029
|
|
125
125
|
chellow/templates/national_grid.html,sha256=8W92tsjlqPSB0J--nyFIi-wzFae9CyDr6fODXLZp8ic,991
|
|
126
126
|
chellow/templates/non_core_auto_importer.html,sha256=s9SluRN1bHTHjd8GP6uFhk6LrZYG8dqBG3y94zUKe5Q,944
|
|
127
127
|
chellow/templates/non_core_contract.html,sha256=BdGtxErTvw4DwXLb6B2vimuU6ode3fFA-90kBmHCwYc,1754
|
|
128
|
-
chellow/templates/non_core_contract_edit.html,sha256=
|
|
128
|
+
chellow/templates/non_core_contract_edit.html,sha256=rjY174SH_wXFU345VRIfN_yjd-jc9QQjzhyrJAf3VEk,2961
|
|
129
129
|
chellow/templates/non_core_contracts.html,sha256=vIrVdn4NUj58Uy17REs_fy2JBQzPkjcg63bg7q6kELg,661
|
|
130
130
|
chellow/templates/non_core_rate_script.html,sha256=CqGnuWdzhk_o_2xNFcF8rgk0p7SNh0B0c3k1JzOtn98,1283
|
|
131
131
|
chellow/templates/non_core_rate_script_add.html,sha256=Qx8_cYFRQZrXSyR3uf_8OxUAUz3PqyYc4V11lTU18sE,690
|
|
@@ -363,6 +363,6 @@ chellow/templates/g/supply_note_edit.html,sha256=6UQf_qbhFDys3cVsTp-c7ABWZpggW9R
|
|
|
363
363
|
chellow/templates/g/supply_notes.html,sha256=WR3YwGh_qqTklSJ7JqWX6BKBc9rk_jMff4RiWZiF2CM,936
|
|
364
364
|
chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
|
|
365
365
|
chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
|
|
366
|
-
chellow-
|
|
367
|
-
chellow-
|
|
368
|
-
chellow-
|
|
366
|
+
chellow-1706803240.0.0.dist-info/METADATA,sha256=eS7h8kUbbn3KHM1frcHE5TJ-nYwOMuH4tt_6iiugPB8,12203
|
|
367
|
+
chellow-1706803240.0.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
|
|
368
|
+
chellow-1706803240.0.0.dist-info/RECORD,,
|
|
File without changes
|