chellow 1714484335.0.0__py3-none-any.whl → 1715253565.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/computer.py CHANGED
@@ -552,6 +552,7 @@ class DataSource:
552
552
  self.era_map_mop_contracts = self.era_map.get("mop_contracts", {})
553
553
  self.era_map_cops = self.era_map.get("cops", {})
554
554
  self.era_map_comms = self.era_map.get("comms", {})
555
+ self.era_map_dtc_meter_types = self.era_map.get("dtc_meter_types", {})
555
556
  self.era_map_mpan_cores = self.era_map.get("mpan_cores", {})
556
557
  self.era_map_dnos = self.era_map.get("dnos", {})
557
558
  self.era_map_gsp_groups = self.era_map.get("gsp_groups", {})
@@ -672,9 +673,16 @@ class SiteSource(DataSource):
672
673
  else:
673
674
  self.sc = era.imp_sc
674
675
 
675
- self.properties = self.era_map.get("properties_overwritten", {})
676
- self.properties.update(era.props)
677
- self.properties.update(self.era_map.get("properties_overwrite", {}))
676
+ if era.dtc_meter_type is None:
677
+ era_dtc_meter_type_code = None
678
+ else:
679
+ era_dtc_meter_type_code = era.dtc_meter_type.code
680
+ if era_dtc_meter_type_code in self.era_map_dtc_meter_types:
681
+ self.dtc_meter_type_code = self.era_map_dtc_meter_types[
682
+ era_dtc_meter_type_code
683
+ ]
684
+ else:
685
+ self.dtc_meter_type_code = era_dtc_meter_type_code
678
686
 
679
687
  self.is_import = True
680
688
  self.voltage_level_code = self.llfc.voltage_level.code
@@ -1051,9 +1059,16 @@ class SupplySource(DataSource):
1051
1059
  else:
1052
1060
  self.comm_code = era.comm.code
1053
1061
 
1054
- self.properties = dict(self.era_map.get("properties_overwritten", {}))
1055
- self.properties.update(era.props)
1056
- self.properties.update(self.era_map.get("properties_overwrite", {}))
1062
+ if era.dtc_meter_type is None:
1063
+ era_dtc_meter_type_code = None
1064
+ else:
1065
+ era_dtc_meter_type_code = era.dtc_meter_type.code
1066
+ if era_dtc_meter_type_code in self.era_map_dtc_meter_types:
1067
+ self.dtc_meter_type_code = self.era_map_dtc_meter_types[
1068
+ era_dtc_meter_type_code
1069
+ ]
1070
+ else:
1071
+ self.dtc_meter_type_code = era_dtc_meter_type_code
1057
1072
 
1058
1073
  self.id = self.mpan_core
1059
1074
  self.msn = era.msn
@@ -1632,18 +1647,6 @@ def _read_generator(sess, supply, start, is_forwards, is_prev):
1632
1647
  if bill.id != r.bill.id:
1633
1648
  continue
1634
1649
 
1635
- era = supply.find_era_at(sess, dt)
1636
- if era is None:
1637
- era_coeff = None
1638
- else:
1639
- era_properties = PropDict(
1640
- chellow.utils.url_root + "eras/" + str(era.id), loads(era.properties)
1641
- )
1642
- try:
1643
- era_coeff = float(era_properties["coefficient"])
1644
- except KeyError:
1645
- era_coeff = None
1646
-
1647
1650
  reads = {}
1648
1651
  coeffs = {}
1649
1652
  for coeff, value, tpr_code in sess.query(
@@ -1656,7 +1659,7 @@ def _read_generator(sess, supply, start, is_forwards, is_prev):
1656
1659
  r_dt == dt,
1657
1660
  ):
1658
1661
  reads[tpr_code] = value
1659
- coeffs[tpr_code] = coeff if era_coeff is None else era_coeff
1662
+ coeffs[tpr_code] = coeff
1660
1663
 
1661
1664
  yield {
1662
1665
  "date": dt,
chellow/e/views.py CHANGED
@@ -42,6 +42,7 @@ from chellow.models import (
42
42
  Comm,
43
43
  Contract,
44
44
  Cop,
45
+ DtcMeterType,
45
46
  EnergisationStatus,
46
47
  Era,
47
48
  GeneratorType,
@@ -49,7 +50,6 @@ from chellow.models import (
49
50
  HhDatum,
50
51
  Laf,
51
52
  Llfc,
52
- METER_TYPES,
53
53
  MarketRole,
54
54
  MeasurementRequirement,
55
55
  MeterPaymentType,
@@ -1505,15 +1505,14 @@ def dno_get(dno_id):
1505
1505
 
1506
1506
  @e.route("/dtc_meter_types")
1507
1507
  def dtc_meter_types_get():
1508
- return render_template("dtc_meter_types.html", dtc_meter_types=METER_TYPES)
1508
+ dtc_meter_types = g.sess.scalars(select(DtcMeterType).order_by(DtcMeterType.code))
1509
+ return render_template("dtc_meter_types.html", dtc_meter_types=dtc_meter_types)
1509
1510
 
1510
1511
 
1511
- @e.route("/dtc_meter_types/<code>")
1512
- def dtc_meter_type_get(code):
1513
- desc = METER_TYPES[code]
1514
- return render_template(
1515
- "dtc_meter_type.html", dtc_meter_type_code=code, dtc_meter_type_description=desc
1516
- )
1512
+ @e.route("/dtc_meter_types/<int:dtc_meter_type_id>")
1513
+ def dtc_meter_type_get(dtc_meter_type_id):
1514
+ dtc_meter_type = DtcMeterType.get_by_id(g.sess, dtc_meter_type_id)
1515
+ return render_template("dtc_meter_type.html", dtc_meter_type=dtc_meter_type)
1517
1516
 
1518
1517
 
1519
1518
  @e.route("/duration_report")
@@ -1569,6 +1568,7 @@ def era_edit_get(era_id):
1569
1568
  cops = g.sess.query(Cop).order_by(Cop.code)
1570
1569
  comms = g.sess.query(Comm).order_by(Comm.code)
1571
1570
  gsp_groups = g.sess.query(GspGroup).order_by(GspGroup.code)
1571
+ dtc_meter_types = g.sess.scalars(select(DtcMeterType).order_by(DtcMeterType.code))
1572
1572
  mop_contracts = (
1573
1573
  g.sess.query(Contract)
1574
1574
  .join(MarketRole)
@@ -1602,6 +1602,7 @@ def era_edit_get(era_id):
1602
1602
  cops=cops,
1603
1603
  comms=comms,
1604
1604
  gsp_groups=gsp_groups,
1605
+ dtc_meter_types=dtc_meter_types,
1605
1606
  mop_contracts=mop_contracts,
1606
1607
  dc_contracts=dc_contracts,
1607
1608
  supplier_contracts=supplier_contracts,
@@ -1619,6 +1620,9 @@ def era_edit_form_get(era_id):
1619
1620
  select(EnergisationStatus).order_by(EnergisationStatus.code)
1620
1621
  )
1621
1622
  default_energisation_status = EnergisationStatus.get_by_code(g.sess, "E")
1623
+ dtc_meter_types = g.sess.scalars(
1624
+ select(DtcMeterType).order_by(DtcMeterType.code)
1625
+ )
1622
1626
 
1623
1627
  if "start_year" in request.values:
1624
1628
  start_date = req_date("start")
@@ -1938,6 +1942,7 @@ def era_edit_form_get(era_id):
1938
1942
  start_date=start_date,
1939
1943
  imp_llfcs=imp_llfcs,
1940
1944
  exp_llfcs=exp_llfcs,
1945
+ dtc_meter_types=dtc_meter_types,
1941
1946
  )
1942
1947
  except BadRequest as e:
1943
1948
  g.sess.rollback()
@@ -1954,6 +1959,7 @@ def era_edit_form_get(era_id):
1954
1959
  sscs=sscs,
1955
1960
  mtc_participants=mtc_participants,
1956
1961
  mtc_participant=mtc_participant,
1962
+ dtc_meter_types=dtc_meter_types,
1957
1963
  )
1958
1964
 
1959
1965
 
@@ -2013,7 +2019,11 @@ def era_edit_post(era_id):
2013
2019
  energisation_status = EnergisationStatus.get_by_id(
2014
2020
  g.sess, energisation_status_id
2015
2021
  )
2016
- properties = req_zish("properties")
2022
+ dtc_meter_type_id = req_int_none("dtc_meter_type_id")
2023
+ if dtc_meter_type_id is None:
2024
+ dtc_meter_type = None
2025
+ else:
2026
+ dtc_meter_type = DtcMeterType.get_by_id(g.sess, dtc_meter_type_id)
2017
2027
 
2018
2028
  has_imp_mpan = req_bool("has_imp_mpan")
2019
2029
  has_exp_mpan = req_bool("has_exp_mpan")
@@ -2072,7 +2082,7 @@ def era_edit_post(era_id):
2072
2082
  comm,
2073
2083
  ssc_code,
2074
2084
  energisation_status,
2075
- properties,
2085
+ dtc_meter_type,
2076
2086
  imp_mpan_core,
2077
2087
  imp_llfc_code,
2078
2088
  imp_supplier_contract,
@@ -4626,7 +4636,12 @@ def site_add_e_supply_post(site_id):
4626
4636
  energisation_status = EnergisationStatus.get_by_id(
4627
4637
  g.sess, energisation_status_id
4628
4638
  )
4629
- properties = req_zish("properties")
4639
+ dtc_meter_type_id = req_int_none("dtc_meter_type_id")
4640
+ if dtc_meter_type_id is None:
4641
+ dtc_meter_type = None
4642
+ else:
4643
+ dtc_meter_type = DtcMeterType.get_by_id(g.sess, dtc_meter_type_id)
4644
+
4630
4645
  if "generator_type_id" in request.form:
4631
4646
  generator_type_id = req_int("generator_type_id")
4632
4647
  generator_type = GeneratorType.get_by_id(g.sess, generator_type_id)
@@ -4703,7 +4718,7 @@ def site_add_e_supply_post(site_id):
4703
4718
  comm,
4704
4719
  None if ssc is None else ssc.code,
4705
4720
  energisation_status,
4706
- properties,
4721
+ dtc_meter_type,
4707
4722
  imp_mpan_core,
4708
4723
  imp_llfc_code,
4709
4724
  imp_supplier_contract,
chellow/general_import.py CHANGED
@@ -9,7 +9,7 @@ from sqlalchemy.sql.expression import false
9
9
 
10
10
  from werkzeug.exceptions import BadRequest
11
11
 
12
- from zish import ZishException, loads
12
+ from zish import loads
13
13
 
14
14
  from chellow.models import (
15
15
  Bill,
@@ -18,6 +18,7 @@ from chellow.models import (
18
18
  Comm,
19
19
  Contract,
20
20
  Cop,
21
+ DtcMeterType,
21
22
  EnergisationStatus,
22
23
  Era,
23
24
  GContract,
@@ -389,11 +390,11 @@ def general_import_era(sess, action, vals, args):
389
390
  else:
390
391
  energisation_status = EnergisationStatus.get_by_code(sess, es_code)
391
392
 
392
- properties_str = add_arg(args, "Properties", vals, 14)
393
- if properties_str == NO_CHANGE:
394
- properties = loads(existing_era.properties)
393
+ dtc_meter_type_code = add_arg(args, "DTC Meter Type", vals, 14)
394
+ if dtc_meter_type_code == NO_CHANGE:
395
+ dtc_meter_type = existing_era.dtc_meter_type
395
396
  else:
396
- properties = loads(properties_str)
397
+ dtc_meter_type = DtcMeterType.get_by_code(sess, dtc_meter_type_code)
397
398
 
398
399
  imp_mpan_core = add_arg(args, "Import MPAN Core", vals, 15)
399
400
  if imp_mpan_core == NO_CHANGE:
@@ -519,7 +520,7 @@ def general_import_era(sess, action, vals, args):
519
520
  comm,
520
521
  ssc_code,
521
522
  energisation_status,
522
- properties,
523
+ dtc_meter_type,
523
524
  imp_mpan_core,
524
525
  imp_llfc_code,
525
526
  imp_supplier_contract,
@@ -1275,11 +1276,8 @@ def general_import_supply(sess, action, vals, args):
1275
1276
  energisation_status = EnergisationStatus.get_by_code(
1276
1277
  sess, energisation_status_code
1277
1278
  )
1278
- properties_str = add_arg(args, "Properties", vals, 19)
1279
- try:
1280
- properties = loads(properties_str)
1281
- except ZishException as e:
1282
- raise BadRequest(f"Can't parse the properties field. {e}")
1279
+ dtc_meter_type_code = add_arg(args, "DTC Meter Type", vals, 19)
1280
+ dtc_meter_type = DtcMeterType.get_by_code(sess, dtc_meter_type_code)
1283
1281
  imp_mpan_core = add_arg(args, "Import MPAN Core", vals, 20)
1284
1282
  if len(imp_mpan_core) == 0:
1285
1283
  imp_mpan_core = None
@@ -1356,7 +1354,7 @@ def general_import_supply(sess, action, vals, args):
1356
1354
  comm,
1357
1355
  ssc_code,
1358
1356
  energisation_status,
1359
- properties,
1357
+ dtc_meter_type,
1360
1358
  imp_mpan_core,
1361
1359
  imp_llfc_code,
1362
1360
  imp_supplier_contract,
chellow/models.py CHANGED
@@ -2452,6 +2452,38 @@ class Laf(Base, PersistentClass):
2452
2452
  self.value = value
2453
2453
 
2454
2454
 
2455
+ # J0483 in https://www.electralink.co.uk/data-catalogues/dtc-catalogue/
2456
+ class DtcMeterType(Base, PersistentClass):
2457
+ __tablename__ = "dtc_meter_type"
2458
+ id = Column(Integer, primary_key=True)
2459
+ code = Column(String, nullable=False, unique=True)
2460
+ description = Column(String, nullable=False)
2461
+ eras = relationship("Era", backref="dtc_meter_type")
2462
+
2463
+ def __init__(self, code, description):
2464
+ self.code = code
2465
+ self.description = description
2466
+
2467
+ @classmethod
2468
+ def insert(cls, sess, code, description):
2469
+ dtc_meter_type = cls(code, description)
2470
+ sess.add(dtc_meter_type)
2471
+ return dtc_meter_type
2472
+
2473
+ @staticmethod
2474
+ def find_by_code(sess, code):
2475
+ return sess.execute(
2476
+ select(DtcMeterType).where(DtcMeterType.code == code)
2477
+ ).scalar_one_or_none()
2478
+
2479
+ @classmethod
2480
+ def get_by_code(cls, sess, code):
2481
+ dtc_meter_type = cls.find_by_code(sess, code)
2482
+ if dtc_meter_type is None:
2483
+ raise Exception(f"Can't find the DTC meter type with code {code}.")
2484
+ return dtc_meter_type
2485
+
2486
+
2455
2487
  class MeterType(Base, PersistentClass):
2456
2488
  __tablename__ = "meter_type"
2457
2489
  id = Column(Integer, primary_key=True)
@@ -3234,42 +3266,6 @@ class EnergisationStatus(Base, PersistentClass):
3234
3266
  return energisation_status
3235
3267
 
3236
3268
 
3237
- METER_TYPES = {
3238
- "H": "Half Hourly",
3239
- "K": "Key",
3240
- "LAG": "Lag",
3241
- "LEAD": "Lead",
3242
- "MAIN": "Main",
3243
- "N": "Non-Half Hourly",
3244
- "NCAMR": "Non-remotely Configurable Automated Meter Reading",
3245
- "NSS": "A meter that meets the definition of an ADM but is not compliant "
3246
- "with any version of SMETS",
3247
- "RCAMR": "Remotely Configurable Automated Meter Reading without remote "
3248
- "enable/disable capability",
3249
- "RCAMY": "Remotely Configurable Automated Meter Reading with remote "
3250
- "enable/disable capability",
3251
- "S": "Smartcard Prepayment",
3252
- "S1": "A meter that is compliant with the Smart Metering Equipment "
3253
- "Technical Specifications 1 (SMETS1)",
3254
- "S2A": "A single element meter that is compliant with SMETS2",
3255
- "S2B": "A twin element meter that is compliant with SMETS2",
3256
- "S2C": "A polyphase meter that is compliant with SMETS2",
3257
- "S2AD": "A single element meter with one or more ALCS that is compliant "
3258
- "with SMETS2",
3259
- "S2BD": "A twin element meter with one or more ALCS that is compliant "
3260
- "with SMETS2",
3261
- "S2CD": "A polyphase meter with one or more ALCS that is compliant with " "SMETS2",
3262
- "S2ADE": "Single element meter with one or more ALCS and Boost Function "
3263
- "that is compliant with SMETS2",
3264
- "S2BDE": "A twin element meter with one or more ALCS and Boost Function "
3265
- "that is compliant with SMETS2",
3266
- "S2CDE": "A polyphase meter with one or more ALCS and Boost Function that "
3267
- "is compliant with SMETS2",
3268
- "SPECL": "Special",
3269
- "T": "Token",
3270
- }
3271
-
3272
-
3273
3269
  class Era(Base, PersistentClass):
3274
3270
  __tablename__ = "era"
3275
3271
  id = Column(Integer, primary_key=True)
@@ -3298,7 +3294,7 @@ class Era(Base, PersistentClass):
3298
3294
  energisation_status_id = Column(
3299
3295
  Integer, ForeignKey("energisation_status.id"), nullable=False
3300
3296
  )
3301
- properties = Column(Text, nullable=False)
3297
+ dtc_meter_type_id = Column(Integer, ForeignKey("dtc_meter_type.id"))
3302
3298
  imp_mpan_core = Column(String)
3303
3299
  imp_llfc_id = Column(Integer, ForeignKey("llfc.id"))
3304
3300
  imp_llfc = relationship("Llfc", primaryjoin="Llfc.id==Era.imp_llfc_id")
@@ -3441,7 +3437,7 @@ class Era(Base, PersistentClass):
3441
3437
  self.comm,
3442
3438
  None if self.ssc is None else self.ssc.code,
3443
3439
  self.energisation_status,
3444
- loads(self.properties),
3440
+ self.dtc_meter_type,
3445
3441
  self.imp_mpan_core,
3446
3442
  None if self.imp_llfc is None else self.imp_llfc.code,
3447
3443
  self.imp_supplier_contract,
@@ -3470,7 +3466,7 @@ class Era(Base, PersistentClass):
3470
3466
  comm,
3471
3467
  ssc_code,
3472
3468
  energisation_status,
3473
- properties,
3469
+ dtc_meter_type,
3474
3470
  imp_mpan_core,
3475
3471
  imp_llfc_code,
3476
3472
  imp_supplier_contract,
@@ -3521,22 +3517,7 @@ class Era(Base, PersistentClass):
3521
3517
  "A NHH supply must have a Standard Settlement Configuration."
3522
3518
  )
3523
3519
  self.energisation_status = energisation_status
3524
-
3525
- if isinstance(properties, dict):
3526
- try:
3527
- meter_type = properties["meter_type"]
3528
- if meter_type not in METER_TYPES:
3529
- raise BadRequest(
3530
- f"The meter type {meter_type} must be one of {METER_TYPES}."
3531
- )
3532
- except KeyError:
3533
- pass
3534
-
3535
- self.properties = dumps(properties)
3536
- else:
3537
- raise Exception(
3538
- f"The properties argument must be a dict, rather than {properties}."
3539
- )
3520
+ self.dtc_meter_type = dtc_meter_type
3540
3521
 
3541
3522
  locs = locals()
3542
3523
  voltage_level = None
@@ -3775,29 +3756,13 @@ class Era(Base, PersistentClass):
3775
3756
  sess.delete(channel)
3776
3757
  sess.flush()
3777
3758
 
3778
- @property
3779
- def props(self):
3780
- if not hasattr(self, "_props"):
3781
- self._props = loads(self.properties)
3782
- return self._props
3783
-
3784
3759
  @property
3785
3760
  def meter_category(self):
3786
3761
  if not hasattr(self, "_meter_category"):
3787
- meter_type = self.props.get("meter_type")
3788
- try:
3789
- cat = METER_CATEGORY[meter_type]
3790
- except KeyError:
3791
- if self.pc.code == "00":
3792
- cat = "hh"
3793
- elif len(self.channels) > 0:
3794
- cat = "amr"
3795
- elif self.mtc_participant.meter_type.code in ["UM", "PH"]:
3796
- cat = "unmetered"
3797
- else:
3798
- cat = "nhh"
3762
+ self._meter_category = METER_CATEGORY[
3763
+ None if self.dtc_meter_type is None else self.dtc_meter_type.code
3764
+ ]
3799
3765
 
3800
- self._meter_category = cat
3801
3766
  return self._meter_category
3802
3767
 
3803
3768
  def get_physical_site(self, sess):
@@ -3808,7 +3773,42 @@ class Era(Base, PersistentClass):
3808
3773
  )
3809
3774
 
3810
3775
 
3811
- METER_CATEGORY = {"H": "hh", "N": "nhh", "S1": "amr"}
3776
+ METER_CATEGORY = {
3777
+ None: "unmetered",
3778
+ "CHECK": "hh",
3779
+ "H": "hh",
3780
+ "K": "nhh",
3781
+ "LAG_": "hh",
3782
+ "LEAD_": "hh",
3783
+ "MAIN_": "hh",
3784
+ "N": "nhh",
3785
+ "NCAMR": "amr",
3786
+ "NSS": "amr",
3787
+ "RCAMR": "amr",
3788
+ "RCAMY": "amr",
3789
+ "S": "nhh",
3790
+ "S1": "amr",
3791
+ "S2A": "amr",
3792
+ "S2B": "amr",
3793
+ "S2C": "amr",
3794
+ "S2AD": "amr",
3795
+ "S2BD": "amr",
3796
+ "S2CDE": "amr",
3797
+ "SPECL": "nhh",
3798
+ "T": "nhh",
3799
+ "2ADF": "amr",
3800
+ "2ADEF": "amr",
3801
+ "2AEF": "amr",
3802
+ "2AF": "amr",
3803
+ "2BF": "amr",
3804
+ "2BDF": "amr",
3805
+ "2BDEF": "amr",
3806
+ "2BEF": "amr",
3807
+ "2CDEF": "amr",
3808
+ "2CF": "amr",
3809
+ "2CDF": "amr",
3810
+ "2CEF": "amr",
3811
+ }
3812
3812
 
3813
3813
 
3814
3814
  class Channel(Base, PersistentClass):
@@ -4521,7 +4521,7 @@ class Supply(Base, PersistentClass):
4521
4521
  template_era.comm,
4522
4522
  None if template_era.ssc is None else template_era.ssc.code,
4523
4523
  template_era.energisation_status,
4524
- loads(template_era.properties),
4524
+ template_era.dtc_meter_type,
4525
4525
  template_era.imp_mpan_core,
4526
4526
  imp_llfc_code,
4527
4527
  template_era.imp_supplier_contract,
@@ -6567,6 +6567,94 @@ def insert_voltage_levels(sess):
6567
6567
  VoltageLevel.insert(sess, code, desc)
6568
6568
 
6569
6569
 
6570
+ def insert_dtc_meter_types(sess):
6571
+ for code, desc in (
6572
+ ("CHECK", "Check"),
6573
+ ("H", "Half Hourly"),
6574
+ ("K", "Key"),
6575
+ ("LAG_", "Lag"),
6576
+ ("LEAD_", "Lead"),
6577
+ ("MAIN_", "Main"),
6578
+ ("N", "Non-Half Hourly"),
6579
+ ("NCAMR", "Non-remotely Configurable Automated Meter Reading"),
6580
+ (
6581
+ "NSS",
6582
+ "A meter that meets the definition of an ADM but is not compliant with "
6583
+ "any version of SMETS",
6584
+ ),
6585
+ (
6586
+ "RCAMR",
6587
+ "Remotely Configurable Automated Meter Reading without remote "
6588
+ "enable/disable capability",
6589
+ ),
6590
+ (
6591
+ "RCAMY",
6592
+ "Remotely Configurable Automated Meter Reading with remote "
6593
+ "enable/disable capability",
6594
+ ),
6595
+ ("S", "Smartcard Prepayment"),
6596
+ (
6597
+ "S1",
6598
+ "A meter that is compliant with the Smart Metering Equipment Technical "
6599
+ "Specifications 1 (SMETS1)",
6600
+ ),
6601
+ ("S2A", "A single element meter that is compliant with SMETS2"),
6602
+ ("S2B", "A twin element meter that is compliant with SMETS2"),
6603
+ ("S2C", "A polyphase meter that is compliant with SMETS2"),
6604
+ (
6605
+ "S2AD",
6606
+ "A single element meter with one or more ALCS that is compliant with "
6607
+ "SMETS2",
6608
+ ),
6609
+ (
6610
+ "S2BD",
6611
+ "A twin element meter with one or more ALCS that is compliant with "
6612
+ "SMETS2",
6613
+ ),
6614
+ (
6615
+ "S2CDE",
6616
+ "A polyphase meter with one or more ALCS and Boost Function that is "
6617
+ "compliant with SMETS2",
6618
+ ),
6619
+ ("SPECL", "Special"),
6620
+ ("T", "Token"),
6621
+ (
6622
+ "2ADF",
6623
+ "Single Element with ALCS and Auxiliary Proportional Controller (APC) "
6624
+ "that is compliant with SMETS2",
6625
+ ),
6626
+ (
6627
+ "2ADEF",
6628
+ "Single Element with ALCS, Boost Function and APC that is compliant "
6629
+ "with SMETS2",
6630
+ ),
6631
+ (
6632
+ "2AEF",
6633
+ "Single Element with Boost Function and APC that is compliant with SMETS2",
6634
+ ),
6635
+ ("2AF", "Single Element with APC that is compliant with SMETS2"),
6636
+ ("2BF", "Twin Element with APC that is compliant with SMETS2"),
6637
+ ("2BDF", "Twin Element with ALCS and APC that is compliant with SMETS2"),
6638
+ (
6639
+ "2BDEF",
6640
+ "Twin Element with ALCS, Boost Function and APC that is compliant with "
6641
+ "SMETS2",
6642
+ ),
6643
+ (
6644
+ "2BEF",
6645
+ "Twin Element with Boost Function and APC that is compliant with SMETS2",
6646
+ ),
6647
+ (
6648
+ "2CDEF",
6649
+ "Polyphase with ALCS, Boost Function and APC that is compliant with SMETS2",
6650
+ ),
6651
+ ("2CF", "Polyphase with APC that is compliant with SMETS2"),
6652
+ ("2CDF", "Polyphase with ALCS and APC that is compliant with SMETS2"),
6653
+ ("2CEF", "Polyphase with Boost Function and APC that is compliant with SMETS2"),
6654
+ ):
6655
+ DtcMeterType.insert(sess, code, desc)
6656
+
6657
+
6570
6658
  def db_init(sess, root_path):
6571
6659
  db_name = config["PGDATABASE"]
6572
6660
  log_message("Initializing database.")
@@ -6658,6 +6746,9 @@ def db_init(sess, root_path):
6658
6746
  ):
6659
6747
  Contract.insert_non_core(sess, name, "", properties, last_month_start, None, {})
6660
6748
 
6749
+ insert_dtc_meter_types(sess)
6750
+ sess.commit()
6751
+
6661
6752
  insert_g_read_types(sess)
6662
6753
  sess.commit()
6663
6754
 
@@ -7295,6 +7386,53 @@ def db_upgrade_45_to_46(sess, root_path):
7295
7386
  )
7296
7387
 
7297
7388
 
7389
+ def db_upgrade_46_to_47(sess, root_path):
7390
+ insert_dtc_meter_types(sess)
7391
+ sess.flush()
7392
+
7393
+ sess.execute(
7394
+ text(
7395
+ "alter table era add dtc_meter_type_id integer references dtc_meter_type "
7396
+ "(id);"
7397
+ )
7398
+ )
7399
+ for era_id, pc_id, era_properties, mtc_participant_id in sess.execute(
7400
+ text("select era.id, era.pc_id, era.properties, mtc_participant_id from era")
7401
+ ):
7402
+ dtc_meter_type_id = None
7403
+ props = loads(era_properties)
7404
+ if "meter_type" in props:
7405
+ mt_code = props["meter_type"]
7406
+ dtc_meter_type = DtcMeterType.find_by_code(sess, mt_code)
7407
+ dtc_meter_type_id = dtc_meter_type.id
7408
+
7409
+ if dtc_meter_type_id is None:
7410
+ mtc_participant = MtcParticipant.get_by_id(sess, mtc_participant_id)
7411
+ if mtc_participant.meter_type.code not in ["UM", "PH"]:
7412
+ pc = Pc.get_by_id(sess, pc_id)
7413
+ if pc.code == "00":
7414
+ dtc_meter_type_code = "H"
7415
+ else:
7416
+ channels = sess.scalars(
7417
+ select(Channel).where(Channel.era_id == era_id)
7418
+ ).all()
7419
+ if len(channels) > 0:
7420
+ dtc_meter_type_code = "RCAMR"
7421
+ else:
7422
+ dtc_meter_type_code = "N"
7423
+ dtc_meter_type = DtcMeterType.get_by_code(sess, dtc_meter_type_code)
7424
+ dtc_meter_type_id = dtc_meter_type.id
7425
+
7426
+ sess.execute(
7427
+ text(
7428
+ "UPDATE era SET dtc_meter_type_id = :dtc_meter_type_id "
7429
+ "where id = :era_id"
7430
+ ),
7431
+ params={"dtc_meter_type_id": dtc_meter_type_id, "era_id": era_id},
7432
+ )
7433
+ sess.execute(text("alter table era drop column properties;"))
7434
+
7435
+
7298
7436
  upgrade_funcs = [None] * 18
7299
7437
  upgrade_funcs.extend(
7300
7438
  [
@@ -7326,6 +7464,7 @@ upgrade_funcs.extend(
7326
7464
  db_upgrade_43_to_44,
7327
7465
  db_upgrade_44_to_45,
7328
7466
  db_upgrade_45_to_46,
7467
+ db_upgrade_46_to_47,
7329
7468
  ]
7330
7469
  )
7331
7470
 
@@ -375,7 +375,7 @@ limit 3
375
375
  latest_mop_bill_date,
376
376
  supply_start_date,
377
377
  supply_finish_date,
378
- era.properties,
378
+ None if era.dtc_meter_type is None else era.dtc_meter_type.code,
379
379
  imp_tnuos_band,
380
380
  ]
381
381
  + channel_values
@@ -447,7 +447,7 @@ def _process(sess, f, date, supply_id, mpan_cores):
447
447
  "Latest MOP Bill Date",
448
448
  "Supply Start Date",
449
449
  "Supply Finish Date",
450
- "Properties",
450
+ "DTC Meter Type",
451
451
  "tnuos_band",
452
452
  "Import ACTIVE?",
453
453
  "Import REACTIVE_IMPORT?",
@@ -484,7 +484,11 @@ def _process(
484
484
  "serial numbers do match. "
485
485
  )
486
486
 
487
- chellow_meter_type = _meter_type(era)
487
+ chellow_dtc_meter_type = era.dtc_meter_type
488
+ if chellow_dtc_meter_type is None:
489
+ chellow_meter_type = None
490
+ else:
491
+ chellow_meter_type = chellow_dtc_meter_type.code
488
492
 
489
493
  if chellow_meter_type != ecoes["meter-type"]:
490
494
  problem += "The DTC meter types don't match."
@@ -560,7 +564,8 @@ def _process(
560
564
 
561
565
  msn = "" if era.msn is None else era.msn
562
566
 
563
- meter_type = _meter_type(era)
567
+ dtc_meter_type = era.dtc_meter_type
568
+ meter_type = "" if dtc_meter_type is None else dtc_meter_type.code
564
569
 
565
570
  values = {
566
571
  "mpan_core": mpan_core,
@@ -605,21 +610,6 @@ def _process(
605
610
  report_run.insert_row(sess, "", titles, values, {})
606
611
 
607
612
 
608
- def _meter_type(era):
609
- props = era.props
610
- try:
611
- return props["meter_type"]
612
- except KeyError:
613
- if era.pc.code == "00":
614
- return "H"
615
- elif len(era.channels) > 0:
616
- return "RCAMR"
617
- elif era.mtc_participant.meter_type.code in ["UM", "PH"]:
618
- return ""
619
- else:
620
- return "N"
621
-
622
-
623
613
  def do_get(sess):
624
614
  show_ignored = req_bool("show_ignored")
625
615
  report_run = ReportRun.insert(
@@ -1,11 +1,11 @@
1
1
  {% extends "base.html" %}
2
2
 
3
3
  {% block title %}
4
- &raquo; DTC Meter Types &raquo; {{dtc_meter_type_code}}
4
+ &raquo; DTC Meter Types &raquo; {{dtc_meter_type.code}}
5
5
  {% endblock %}
6
6
 
7
7
  {% block nav %}
8
- <a href="/e/dtc_meter_types">DTC Meter Types</a> &raquo; {{dtc_meter_type_code}}
8
+ <a href="/e/dtc_meter_types">DTC Meter Types</a> &raquo; {{dtc_meter_type.code}}
9
9
  {% endblock %}
10
10
 
11
11
  {% block content %}
@@ -13,11 +13,11 @@
13
13
  <table>
14
14
  <tr>
15
15
  <th>Code</th>
16
- <td>{{dtc_meter_type_code}}</td>
16
+ <td>{{dtc_meter_type.code}}</td>
17
17
  </tr>
18
18
  <tr>
19
19
  <th>Description</th>
20
- <td>{{dtc_meter_type_description}}</td>
20
+ <td>{{dtc_meter_type.description}}</td>
21
21
  </tr>
22
22
  </table>
23
23
 
@@ -18,10 +18,10 @@
18
18
  </tr>
19
19
  </thead>
20
20
  <tbody>
21
- {% for code, desc in dtc_meter_types.items() %}
21
+ {% for dtc_meter_type in dtc_meter_types %}
22
22
  <tr>
23
- <td><a href="/e/dtc_meter_types/{{code}}">{{code}}</a></td>
24
- <td>{{desc}}</td>
23
+ <td><a href="/e/dtc_meter_types/{{dtc_meter_type.id}}">{{dtc_meter_type.code}}</a></td>
24
+ <td>{{dtc_meter_type.description}}</td>
25
25
  </tr>
26
26
  {% endfor %}
27
27
  </tbody>
@@ -80,6 +80,7 @@
80
80
  {{input_hidden('gsp_group_id', initial=era.supply.gsp_group.id)}}
81
81
  {{input_hidden('mtc_participant_id', initial=era.mtc_participant.id)}}
82
82
  {{input_hidden('ssc_id', initial=era.ssc.id)}}
83
+ {{input_hidden('dtc_meter_type_id', initial=era.dtc_meter_type.id)}}
83
84
  {{input_hidden('name', initial=era.name)}}
84
85
  {{input_hidden('msn', initial=era.msn)}}
85
86
  {{input_hidden('mop_contract_id', initial=era.mop_contract_id)}}
@@ -89,14 +89,14 @@
89
89
  {% endfor %}
90
90
  </select>
91
91
 
92
- <label>Properties</label>
93
- <div>
94
- {{input_textarea('properties', era.properties, 10, 80)}}
95
- <p>
96
- The <code>meter_type</code> property contains a
97
- <a href="/e/dtc_meter_types">DTC Meter Type Code</a>.
98
- </p>
99
- </div>
92
+ <label>DTC Meter Type</label>
93
+ <select name="dtc_meter_type_id">
94
+ {{input_option('dtc_meter_type_id', '', 'Unmetered')}}
95
+ {% for dtc_meter_type in dtc_meter_types %}
96
+ {{input_option('dtc_meter_type_id', dtc_meter_type.id,
97
+ dtc_meter_type.code + ' ' + dtc_meter_type.description, era.dtc_meter_type.id)}}
98
+ {% endfor %}
99
+ </select>
100
100
 
101
101
  <label>Has An Import MPAN?</label>
102
102
  {{input_checkbox('has_imp_mpan')}}
@@ -94,16 +94,8 @@
94
94
  "*": "_L"
95
95
  },
96
96
 
97
- /* Properties are combined with the existing era properties, with the
98
- ones here overwriting any duplicates */
99
- "properties_overwrite": {
100
- "comms_type": "GSM"
101
- },
102
-
103
- /* Properties are combined with the existing era properties, with the
104
- ones here being overwritten by any duplicates */
105
- "properties_overwritten": {
106
- "meter_type": "H"
97
+ "dtc_meter_types": {
98
+ "*": "H"
107
99
  },
108
100
 
109
101
  /* Use hh data rather than register reads for AMRs */
@@ -20,6 +20,7 @@
20
20
  <input type="hidden" name="energisation_status_id"
21
21
  value="{{request.values.energisation_status_id}}">
22
22
  <input type="hidden" name="pc_id" value="{{request.values.pc_id}}">
23
+ <input type="hidden" name="dtc_meter_type_id" value="{{request.values.dtc_meter_type_id}}">
23
24
  <input type="hidden" name="dno_id" value="{{request.values.dno_id}}">
24
25
  <input type="hidden" name="gsp_group_id" value="{{request.values.gsp_group_id}}">
25
26
  <input type="hidden" name="mtc_participant_id"
@@ -116,7 +116,14 @@
116
116
  {% endfor %}
117
117
  </select>
118
118
 
119
- <label>Properties</label> {{input_textarea('properties', '{}', 10, 80)}}
119
+ <label>DTC Meter Type</label>
120
+ <select name="dtc_meter_type_id">
121
+ {{input_option('dtc_meter_type_id', '', 'Unmetered')}}
122
+ {% for dtc_meter_type in dtc_meter_types %}
123
+ {{input_option( 'dtc_meter_type_id', dtc_meter_type.id,
124
+ dtc_meter_type.code + ' ' + dtc_meter_type.description)}}
125
+ {% endfor %}
126
+ </select>
120
127
 
121
128
  <label>Has An Import MPAN?</label> {{input_checkbox('has_imp_mpan')}}
122
129
 
@@ -21,7 +21,7 @@
21
21
  <th rowspan="2">
22
22
  <span title="Standard Settlement Configuration">SSC</span>
23
23
  </th>
24
- <th rowspan="2"><span title="Properties">Props</span></th>
24
+ <th rowspan="2"><span title="DTC Meter Type">Meter</span></th>
25
25
  <th colspan="2"><span title="Meter Operator">MOP</span></th>
26
26
  <th colspan="2"><span title="Data Collector">DC</span></th>
27
27
  <th rowspan="2">
@@ -75,7 +75,8 @@
75
75
  </td>
76
76
  <td rowspan="4">{{ era.msn }}</td>
77
77
  <td rowspan="4">
78
- <a href="/e/mtc_participants/{{era.mtc_participant.id}}" title="{{era.mtc_participant.description}}">{{era.mtc_participant.mtc.code}}</a>
78
+ <a href="/e/mtc_participants/{{era.mtc_participant.id}}"
79
+ title="{{era.mtc_participant.description}}">{{era.mtc_participant.mtc.code}}</a>
79
80
  </td>
80
81
  <td rowspan="4">
81
82
  <a href="/e/cops/{{era.cop.id}}" title="{{era.cop.description}}">{{era.cop.code}}</a>
@@ -88,7 +89,9 @@
88
89
  <a href="/e/sscs/{{era.ssc.id}}" title="{{era.ssc.description}}">{{era.ssc.code}}</a>
89
90
  {% endif %}
90
91
  </td>
91
- <td rowspan="4">{{era.properties}}</td>
92
+ <td rowspan="4">
93
+ <a href="/e/dtc_meter_types/{{era.dtc_meter_type.id}}">{{era.dtc_meter_type.code}}</a>
94
+ </td>
92
95
  <td rowspan="4">
93
96
  <a href="/e/mop_contracts/{{era.mop_contract.id}}">{{era.mop_contract.name}}</a>
94
97
  </td>
@@ -90,11 +90,9 @@
90
90
  <td>Meter Timeswitch Class</td>
91
91
  <td>CoP</td>
92
92
  <td>Comms Type</td>
93
- <td>
94
- Standard Settlement Configuration (blank for HH supplies)
95
- </td>
93
+ <td>Standard Settlement Configuration (blank for HH supplies)</td>
96
94
  <td>Energisation Status</td>
97
- <td>Properties</td>
95
+ <td>DTC Meter Type</td>
98
96
  <td>Import MPAN Core</td>
99
97
  <td>Import LLFC</td>
100
98
  <td>Import Supply Capacity</td>
@@ -137,7 +135,7 @@
137
135
  <td>Comms Type</td>
138
136
  <td>SSC</td>
139
137
  <td>Energisation Status</td>
140
- <td>Properties</td>
138
+ <td>DTC Meter Type</td>
141
139
  <td>Import MPAN Core</td>
142
140
  <td>Import LLFC</td>
143
141
  <td>Import Supply Capacity</td>
@@ -173,7 +171,7 @@
173
171
  <td>Comms Type</td>
174
172
  <td>SSC</td>
175
173
  <td>Energisation Status</td>
176
- <td>Properties</td>
174
+ <td>DTC Meter Type</td>
177
175
  <td>Import MPAN Core</td>
178
176
  <td>Import LLFC</td>
179
177
  <td>Import Supply Capacity</td>
@@ -31,7 +31,7 @@
31
31
 
32
32
  {%- macro input_option(name, item_id, desc, initial=None) -%}
33
33
  <option value="{{ item_id }}"
34
- {%- if request.values[name] -%}
34
+ {%- if name in request.values -%}
35
35
  {%- if request.values[name] == '' ~ item_id %} selected
36
36
  {%- endif -%}
37
37
  {%- else -%}
chellow/views.py CHANGED
@@ -1246,7 +1246,7 @@ def downloads_get():
1246
1246
  files.append(
1247
1247
  {
1248
1248
  "name": fl,
1249
- "last_modified": Datetime.utcfromtimestamp(statinfo.st_mtime),
1249
+ "last_modified": to_utc(Datetime.utcfromtimestamp(statinfo.st_mtime)),
1250
1250
  "size": statinfo.st_size,
1251
1251
  }
1252
1252
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: chellow
3
- Version: 1714484335.0.0
3
+ Version: 1715253565.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)
@@ -4,14 +4,14 @@ chellow/bank_holidays.py,sha256=T_utYMwe_g1dz5X-aOTdIPryg49SvB7QsWM1yphlqG8,4423
4
4
  chellow/commands.py,sha256=ESBe9ZWj1c3vdZgqMZ9gFvYAB3hRag2R1PzOwuw9yFo,1302
5
5
  chellow/dloads.py,sha256=5SmP-0QPK6xCkd_wjIWh_8FAzN5OxNHCzyEQ1Xb-Y-M,5256
6
6
  chellow/edi_lib.py,sha256=het3R0DBGtXEo-Sy1zvXQuX9EWQ1X6Y33G4l1hYYuds,51859
7
- chellow/general_import.py,sha256=FuDinyFxWJ22plUojTaH6wchU-5AQuHuaI_RjVEeJi8,65818
8
- chellow/models.py,sha256=POIL0dfwZFuqht7xHZaE6KJ7fk4kxMZC2aXzgg5kEFY,236921
7
+ chellow/general_import.py,sha256=l3EHq9zG9Vfl5Ee6XTVrC1nusXo4YGGB4VBmZ_JaJR8,65798
8
+ chellow/models.py,sha256=fZpQAHf4gDoXJXH8GB2-wRPrBYD9o-n8QlvfcSctcxU,241038
9
9
  chellow/national_grid.py,sha256=uxcv0qisHPyzw9AVIYPzsRqwt2XPAcZL-SBR12qcrS0,4364
10
10
  chellow/proxy.py,sha256=cVXIktPlX3tQ1BYcwxq0nJXKE6r3DtFTtfFHPq55HaM,1351
11
11
  chellow/rate_server.py,sha256=fg-Pf_9Hk3bXmC9riPQNGQxBvLvBa_WtNYdwDCjnCSg,5678
12
12
  chellow/testing.py,sha256=Od4HHH6pZrhJ_De118_F55RJEKmAvhUH2S24QE9qFQk,3635
13
13
  chellow/utils.py,sha256=32qPWEGzCPKPhSM7ztpzcR6ZG74sVZanScDIdK50Rq4,19308
14
- chellow/views.py,sha256=KiT4yXI5utC4woQY_-Lh15Tu9HbqnspNKZ1HD9kxLVA,79542
14
+ chellow/views.py,sha256=L_mlM8Xi6u850SXMD2XgWdQmZVRB0QAkSdIN_BIHi-M,79550
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
@@ -19,7 +19,7 @@ chellow/e/bmarketidx.py,sha256=0JCBBnP3xfLq2eFjXO_u-gzHyTizab4Pp6PRK6OZLcw,7134
19
19
  chellow/e/bsuos.py,sha256=hdP9vnOJSuZl46OAkJeUg1XJYvYIBj4J6Sqce1Hy9Vs,15542
20
20
  chellow/e/ccl.py,sha256=30dh_SvlgzsTQPPAJNZWILaMvbeDsv9-P-S1JxS5_SQ,3184
21
21
  chellow/e/cfd.py,sha256=V1DTT5XBQbt8hO1gae1u3315fZ4iuYk3XC7J2sUbhKQ,14352
22
- chellow/e/computer.py,sha256=YL1JFUYfFW-i9DODfvSnp6gTL_MwIfwoWj1TWtOsxPg,67105
22
+ chellow/e/computer.py,sha256=KjHE57I3I7-1zPkyqX0mSjORlyUNfSEhQb2df4sCNkU,67244
23
23
  chellow/e/dno_rate_parser.py,sha256=thNjT7HeAcvwV5vACvyGZ-yYzCs4keiIJEoCL8FjJ3E,21488
24
24
  chellow/e/duos.py,sha256=nwviRjz-qIt3GxIMHk0hItIT4dtKsxOWq9TUC1z-hO8,30864
25
25
  chellow/e/elexon.py,sha256=ALhXS9Es7PV0z9ukPbIramn3cf3iLyFi-PMWPSm5iOs,5487
@@ -38,7 +38,7 @@ chellow/e/system_price.py,sha256=6w5J7bzwFAZubE2zdOFRiS8IIrVP8hkoIOaG2yCt-Ic,623
38
38
  chellow/e/tlms.py,sha256=M33D6YpMixu2KkwSCzDRM3kThLgShg8exp63Obo75l8,8905
39
39
  chellow/e/tnuos.py,sha256=XseYztPUsQXNKuBmystO2kzzwAG9ehCZgpGBTdgSk-A,4313
40
40
  chellow/e/triad.py,sha256=lIQj7EdUrcFwEqleuHZXYU_bfzIwNOqUVVxB3NPQt4A,13710
41
- chellow/e/views.py,sha256=ZezsZhpsf1kH0BywUWdMMjxdYAYTIclksUOWTh_AOrE,214186
41
+ chellow/e/views.py,sha256=iKnzFWNvANSB0yNDhZHo5nKw1Ptl6Q8KHuK003ZTDfg,215030
42
42
  chellow/e/bill_parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=UgWXDPzQkQghyj_lfgBqoSJpHB-t-qOdSaB8qY6GLog,4071
44
44
  chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=-HMoIfa_utXYKA44RuC0Xqv3vd2HLeQU_4P0iBUd3WA,4219
@@ -79,7 +79,7 @@ chellow/reports/report_241.py,sha256=AlFmSHnfG2HWv_ICmWX7fNpPwLHjq7mo1QtOTjSKO3k
79
79
  chellow/reports/report_247.py,sha256=ozgCcee8XeqYbOpZCyU2STJKaz6h2x7TYQogagTaYLw,46626
80
80
  chellow/reports/report_29.py,sha256=KDFjgrLBv4WbG9efCdu_geMR7gT_QV9N97Wfdt7aDc4,2736
81
81
  chellow/reports/report_291.py,sha256=rqBXy6s7hMeYWw-yNX6w_L5t2yz6rNEeos_4xO7wf90,7519
82
- chellow/reports/report_33.py,sha256=O-7vsNcSyY_bErtm7NA-yYBsrjRFdBULsRe_SbE8XJk,16677
82
+ chellow/reports/report_33.py,sha256=laVz-itDbJTdvC6LxLEeuY0eKpYx43Un4adiExPTEEE,16730
83
83
  chellow/reports/report_387.py,sha256=KcClrEOK5IRvePp0Jgbzs1Gwf-_CqYmEtFFlXrr_Z3E,5670
84
84
  chellow/reports/report_41.py,sha256=QQeTshA1Og7N3wPaoZ8ynJzwsvZ1mgSFc7DDkVqIZoM,7447
85
85
  chellow/reports/report_429.py,sha256=0GCc0rQnOSG0fusw69yMMOCxnWApBd3P2sGWIg1py9M,12359
@@ -92,7 +92,7 @@ chellow/reports/report_bills.py,sha256=AHW6tiZAOE0gXDfencPvemE4zqK6eTqfN8_bWQ4RT
92
92
  chellow/reports/report_csv_llfcs.py,sha256=OHSbP64lQ6dlAMcQYgvdANlA4lQyF0iBlwk7V9c9nuo,1944
93
93
  chellow/reports/report_csv_site_hh_data.py,sha256=T-clGDmYdn0ej7zZfL3kDp4Vyd82WzptxEzxx9KqAZg,4270
94
94
  chellow/reports/report_csv_site_snags.py,sha256=gG2sYQrLoIBwCoMUC8rhmAL7Kffh_rvNb9UOX7cYDko,2668
95
- chellow/reports/report_ecoes_comparison.py,sha256=xjTvyfYAZhJeAzRJQmKk3xo5rPB1-QbSF-ARuyeKuTs,21822
95
+ chellow/reports/report_ecoes_comparison.py,sha256=s6d69cORezon-h3RmgewT8_cMpLrpMElmP2TnT-y7yY,21743
96
96
  chellow/reports/report_g_monthly_duration.py,sha256=vI5FKAU8_oThjR5oflPZont7Z7sVAunr0qlMfJsaPJI,12004
97
97
  chellow/reports/report_g_supplies_snapshot.py,sha256=0M0x_0o0985Hu45gUJJJwzfx0DDOAuXBJ1UVUDbQ36g,4718
98
98
  chellow/reports/report_g_supply_virtual_bill.py,sha256=x_KtQ02dwgmXvAEUXJ1poK0BRwqxa-GcbJ5pddEina0,3694
@@ -114,12 +114,12 @@ chellow/templates/csv_sites_monthly_duration.html,sha256=59gErG6KwA57z-qh2EJsVGv
114
114
  chellow/templates/downloads.html,sha256=R9QPcFz-PLJOX7rDlmquIk-Hp9Iq-thzWCTfOexSpXg,937
115
115
  chellow/templates/edi_viewer.html,sha256=szUthgHOdph6Of-7f_1LeC_zYlNJaMeS5ctn6xTAeiM,1437
116
116
  chellow/templates/general_import.html,sha256=SMemHGu466Be3_cAWSS6Hn-Kv-1psbEMDD6NQG6bfbI,1013
117
- chellow/templates/general_imports.html,sha256=9rFbve28ADnfJ4CL45vJbOPG-mAYBETWVa_ctgcXvHg,13050
117
+ chellow/templates/general_imports.html,sha256=aPCS_oxOYOCU25koK9lgF3HSiT8GkLeLYpm6NBjT-mo,13051
118
118
  chellow/templates/home.html,sha256=_ANKmcnlk_PDyZl6SCmejU8d90f3t8EH_rDDPDyYUwE,5657
119
119
  chellow/templates/input_date.html,sha256=rpgB5n0LfN8Y5djN_ZiuSxqdskxzCoKrEqI7hyJkVQo,1248
120
120
  chellow/templates/local_report.html,sha256=pV7_0QwyQ-D3OS9LXrly5pq3qprZnwTCoq6vCnMTkS4,1332
121
121
  chellow/templates/local_reports.html,sha256=4wbfVkY4wUfSSfWjxqIsvCpIsa9k7H_dGAjznrG5jNM,701
122
- chellow/templates/macros.html,sha256=9sGRgLxLmhYTIstfL3MgUDFIoRV89SlwPHmuvMqh-UI,5029
122
+ chellow/templates/macros.html,sha256=zd5P3irbRMXiK6LnWdbv5M0SYX2roZKhEzNTt2_uPyM,5031
123
123
  chellow/templates/national_grid.html,sha256=8W92tsjlqPSB0J--nyFIi-wzFae9CyDr6fODXLZp8ic,991
124
124
  chellow/templates/non_core_auto_importer.html,sha256=s9SluRN1bHTHjd8GP6uFhk6LrZYG8dqBG3y94zUKe5Q,944
125
125
  chellow/templates/non_core_contract.html,sha256=BdGtxErTvw4DwXLb6B2vimuU6ode3fFA-90kBmHCwYc,1754
@@ -199,8 +199,8 @@ chellow/templates/e/dno_rate_script.html,sha256=8wK2GqDyPAPxLsK3waEuGwqerGtWPCu-
199
199
  chellow/templates/e/dno_rate_script_add.html,sha256=LRHN86z1oBceQLtzVbLs9rrcav8DfcDrPYzyvvc7cQA,559
200
200
  chellow/templates/e/dno_rate_script_edit.html,sha256=5hNwZWMdesZywOiUAS_OIAapT8jjebc9qp_U9pkXUgs,1275
201
201
  chellow/templates/e/dnos.html,sha256=j9JV0yU7EFvjT5OKBLXfpweYyE9XZT0CxrzsXQSoNPE,702
202
- chellow/templates/e/dtc_meter_type.html,sha256=8h8elG7YlP27wry6sd7MuVZUdIMqdsd6kdV97dxmo-c,440
203
- chellow/templates/e/dtc_meter_types.html,sha256=TBUU4TVQxmyI6srggoMlXjOlFEd_3wy11rxAu47stFs,467
202
+ chellow/templates/e/dtc_meter_type.html,sha256=iqmF07NcKvepHhYA5YjK0f7zdPgBqDIAbl-xndMKwck,440
203
+ chellow/templates/e/dtc_meter_types.html,sha256=dTAIoaCh8DMUAHil0WQ40auLsjsni8z0MNam_2jl_VI,513
204
204
  chellow/templates/e/duration_report.html,sha256=MrDgLDzbXdGLfpUbZ9U3xSP2H1VF0eK225LM_1U9azA,1493
205
205
  chellow/templates/e/elexon.html,sha256=QW2EKdTMBTIzUkiXpYIHVZidZHNca3GmyiwWKaWkvIY,997
206
206
  chellow/templates/e/em_hh_data.html,sha256=2Ndvpo2ngO2dOpEZa05-6xRCy3IKNkWHJwW6sVjhhWY,2032
@@ -209,8 +209,8 @@ chellow/templates/e/em_site.html,sha256=LQJ1RJe7IJCZ-dsmd-Ku3hhNEeKUq3BimEBKJPNZ
209
209
  chellow/templates/e/em_totals.html,sha256=D_H12qF6b8heVeSGzcl4u7xRvtPLUtM1zWYrwEFRFTM,678
210
210
  chellow/templates/e/energisation_status.html,sha256=hvD1qMpLYjmWWGIrv-5Ko3KbRL3a6MdQXcO3Fr4_cHA,478
211
211
  chellow/templates/e/energisation_statuses.html,sha256=qwRIH7jqKA1MgajsWOeZAH89iRpOfsNW_fAqXymUQ3E,587
212
- chellow/templates/e/era_edit.html,sha256=hW2_8Yt1n6VbT15a3PJ4Tn7wwVKyU-IkYDSLC1ZWCRQ,4022
213
- chellow/templates/e/era_edit_form.html,sha256=NhVp965vVnQw6fneGugkAc0nkojjUncbQdio6IeQwhE,4745
212
+ chellow/templates/e/era_edit.html,sha256=MoJ7yS8BWGz7ptqxDPpBio0cnYDYDOoa4jNcpz4NAbk,4094
213
+ chellow/templates/e/era_edit_form.html,sha256=Yh5SdMVuyJCCeSQH5FgZ1qhWzI_SsuraIvitwtUMGes,4862
214
214
  chellow/templates/e/era_supplier_bill_add.html,sha256=TgcIFuX-_sXXYFsn9yGT-QqMrZe6uLxWoJ-G0f-VELU,2050
215
215
  chellow/templates/e/generator_type.html,sha256=En0lQSU_mc-QLMG5Hx-gDINVoqyfa4X9RYwopzpm33g,439
216
216
  chellow/templates/e/generator_types.html,sha256=672cXDYewLAk32pzp6c8fi2P48FikxRrzTEtx_PlR7Y,535
@@ -272,11 +272,11 @@ chellow/templates/e/read_type.html,sha256=volKteZB79famXrzN_Bgqy9JT9C4a50vXLkuZ0
272
272
  chellow/templates/e/read_types.html,sha256=CknHXNEkBnsAprqI66ftvnnMFBdR_kqI7o26rxjlrJA,473
273
273
  chellow/templates/e/scenario.html,sha256=apBfJY3RcieKsVmNIgyRJEJ89bEYlN-dmX9yXgOkJ7w,1153
274
274
  chellow/templates/e/scenario_add.html,sha256=qQpxvhlrQqrNYiIQTHu_NvSoeSKuRNEJQYwLqRlQ8_U,516
275
- chellow/templates/e/scenario_docs.html,sha256=dvl-2wppHGaVqG16w9PERE_65u2eJAIOTh-lHCX_dW4,5162
275
+ chellow/templates/e/scenario_docs.html,sha256=1nTudJvQSbSAqlMoTojQue7krVO9BAc_YFnz4bDGDi0,4814
276
276
  chellow/templates/e/scenario_edit.html,sha256=Uf64v_qsBP0BxaFEIz214CC_dZXlvro4zvQXH_towhA,1070
277
277
  chellow/templates/e/scenarios.html,sha256=zlNhZvQEcuwLgHObVHS-4THur5Lz9Jf1G6xD98-jamI,847
278
- chellow/templates/e/site_add_e_supply.html,sha256=GqPtk8yYJzMij14SzNREGSpCaVD2YcOJSmu-Dn00bGo,2636
279
- chellow/templates/e/site_add_e_supply_form.html,sha256=rL-hEdT6ORiBHC8yxxoQA-ofFKozOdk47olRkzusvhY,5308
278
+ chellow/templates/e/site_add_e_supply.html,sha256=_gi1ejI4TMTMX9vCW7z2kToR2XKR6qoVh67qp_VrDsM,2731
279
+ chellow/templates/e/site_add_e_supply_form.html,sha256=e6jovPUzquy5E-jsdGD1zt_-62NAgc1rhmbP2M5FoM0,5552
280
280
  chellow/templates/e/site_hh_data.html,sha256=1Ld5IIM3G84tVCAwtlJNGJTnrASS7d84AgaPwwHNEMI,1413
281
281
  chellow/templates/e/site_site_snags.html,sha256=vWpsFyxZj7GOrMXQz2rKq9zOQdVsqeUVtdBzehp9J5w,847
282
282
  chellow/templates/e/site_snag.html,sha256=eZt1H-t-hsoKZBteU9ILpKqKLD0Pf0Uybp8pPQYuTAc,924
@@ -309,7 +309,7 @@ chellow/templates/e/supplier_rate_script_add.html,sha256=Yf2LZEIHbL7qT6oxBCtPf0Z
309
309
  chellow/templates/e/supplier_rate_script_edit.html,sha256=VaYJt8nxHdnuP-zEAuBJC-ibEpjDU1b80hXtdBQH1dg,1968
310
310
  chellow/templates/e/supply.html,sha256=No26xivLm4hA8kRufVvPjrEOE3of7pmZaW_jgTcKSY0,8511
311
311
  chellow/templates/e/supply_edit.html,sha256=Ef4ivmSvj9NAb1Uy43S3TCwheCffV457bdpaoD8XZ_s,2723
312
- chellow/templates/e/supply_eras.html,sha256=dkWAvTe2tdRW9EUmcGvEcHpsR-XXkXV9DyewHDQvED0,19445
312
+ chellow/templates/e/supply_eras.html,sha256=y_Y2V20Q-tyyw6iRP3lE1ZQCAZM7CaRtEr1_CcDICuc,19539
313
313
  chellow/templates/e/supply_hh_data.html,sha256=d9ho4Tq3ZkR5GmxSZr_zHGwCU68PH3aSc4OwFG9i9zE,3587
314
314
  chellow/templates/e/supply_months.html,sha256=2EUF_SWCcjG9GiAw86gco8xR6LXaqCPXfQE5A33TqqI,1927
315
315
  chellow/templates/e/supply_note_add.html,sha256=wsrG7P38h8fj63zVAZXfLogdYxIKnn8qxEJFr3Fna4k,553
@@ -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-1714484335.0.0.dist-info/METADATA,sha256=rv1vLsnUMaxKwBmYgJWpNOmlQzBggEhB_-nRSxb6x8I,12205
367
- chellow-1714484335.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
368
- chellow-1714484335.0.0.dist-info/RECORD,,
366
+ chellow-1715253565.0.0.dist-info/METADATA,sha256=zfAMXSPn0ZYoHngICWZa83lQPQHUn7KeDFIouk05-lk,12205
367
+ chellow-1715253565.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
368
+ chellow-1715253565.0.0.dist-info/RECORD,,