From f87e7d090e397a70e6fd4bb91c1e632600aa9f46 Mon Sep 17 00:00:00 2001 From: davidmunoznovoa Date: Tue, 9 Dec 2025 16:48:14 +0100 Subject: [PATCH 1/4] Parse resolution in p48cierre --- esios/parsers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esios/parsers.py b/esios/parsers.py index 119c570..2d70502 100644 --- a/esios/parsers.py +++ b/esios/parsers.py @@ -117,8 +117,8 @@ def parse_cierre(self, content, program_unit): value = e.get('v') start_str, end_str = value.split('/') start = UTC_TZ.localize(datetime.strptime(start_str, '%Y-%m-%dT%H:%MZ')) - end = UTC_TZ.localize(datetime.strptime(end_str, '%Y-%m-%dT%H:%MZ')) - # print("P48 for UP {} from {} to {}".format(program_unit, start, end)) + elif 'Resolucion' in e.tag: + integrity = 'p' if e.get('v') == 'PT60M' else 'p4' elif 'Intervalo' not in e.tag: continue else: @@ -133,6 +133,7 @@ def parse_cierre(self, content, program_unit): 'utc_timestamp': utc_timestamp, 'local_timestamp': local_timestamp, 'cierre': is_cierre, + 'type': integrity }) return curve From 2d36e833fc249c37dc7f1d61d778f5cabf32f7c6 Mon Sep 17 00:00:00 2001 From: davidmunoznovoa Date: Tue, 9 Dec 2025 18:05:29 +0100 Subject: [PATCH 2/4] p48 qh support --- esios/archives.py | 2 +- esios/parsers.py | 3 ++- spec/parsers_spec.py | 33 ++++++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/esios/archives.py b/esios/archives.py index 6bc544a..8ba5863 100644 --- a/esios/archives.py +++ b/esios/archives.py @@ -42,7 +42,7 @@ def get(self, start_date, end_date, taxonomy_terms=None): date_type = 'datos' start_date = start_date.isoformat() end_date = end_date.isoformat() - locale = 'en' + locale = 'es' param_list = ('locale', 'start_date', 'end_date', 'date_type') if taxonomy_terms: param_list += ('taxonomy_terms',) diff --git a/esios/parsers.py b/esios/parsers.py index 2d70502..01e7f21 100644 --- a/esios/parsers.py +++ b/esios/parsers.py @@ -119,12 +119,13 @@ def parse_cierre(self, content, program_unit): start = UTC_TZ.localize(datetime.strptime(start_str, '%Y-%m-%dT%H:%MZ')) elif 'Resolucion' in e.tag: integrity = 'p' if e.get('v') == 'PT60M' else 'p4' + minutes = 60 if integrity == 'p' else 15 elif 'Intervalo' not in e.tag: continue else: hour = int(e[0].get('v')) value = float(e[1].get('v')) - utc_timestamp = start + relativedelta(hours=hour) + utc_timestamp = start + relativedelta(minutes=minutes*hour) local_timestamp = LOCAL_TZ.normalize(utc_timestamp.astimezone(LOCAL_TZ)) curve.append({ 'up': program_unit, diff --git a/spec/parsers_spec.py b/spec/parsers_spec.py index b7e924d..29a9c2d 100644 --- a/spec/parsers_spec.py +++ b/spec/parsers_spec.py @@ -38,9 +38,8 @@ def validate_json(result): expect(local_ts).to(equal(expected_local_ts)) -def validate_data(result, start, end, cierre=None): +def validate_data(result, start, end, cierre=None, qh=True): data = json.loads(result) - target_data = [x for x in data if start <= LOCAL_TZ.normalize(LOCAL_TZ.localize( datetime.strptime(x['local_timestamp'][:18], '%Y-%m-%d %H:%M:%S'))) <= end] @@ -48,8 +47,12 @@ def validate_data(result, start, end, cierre=None): max_date = max([d['local_timestamp'] for d in target_data]) min_date = min([d['local_timestamp'] for d in target_data]) - hours = int(((end - start).total_seconds() / 3600) + 1) - expect(len(target_data)).to(be_above_or_equal(hours)) # can include True and False values for "cierre" field + if qh: + qhs = int((end - start).total_seconds() / 3600 * 4) + 1 + expect(len(target_data)).to(be_above_or_equal(qhs)) # can include True and False values for "cierre" field + else: + hours = int(((end - start).total_seconds() / 3600) + 1) + expect(len(target_data)).to(be_above_or_equal(hours)) # can include True and False values for "cierre" field expect(min_date).to(equal(str(start))) expect(max_date).to(equal(str(end))) @@ -89,7 +92,7 @@ def validate_data(result, start, end, cierre=None): result = parser.get_data_json('SOMEC01', start, end) validate_json(result) - validate_data(result, start + relativedelta(hours=1), end + relativedelta(seconds=1)) + validate_data(result, start + relativedelta(minutes=15), end + relativedelta(seconds=1)) with context('parses local files'): @@ -130,7 +133,10 @@ def validate_data(result, start, end, cierre=None): validate_json(result) validate_data( - result, LOCAL_TZ.localize(datetime(2020, 9, 15, 1, 0)), LOCAL_TZ.localize(datetime(2020, 9, 16, 0, 0), True) + result, + LOCAL_TZ.localize(datetime(2020, 9, 15, 1, 0)), + LOCAL_TZ.localize(datetime(2020, 9, 16, 0, 0), True), + qh=False ) @@ -140,7 +146,10 @@ def validate_data(result, start, end, cierre=None): validate_json(result) validate_data( - result, LOCAL_TZ.localize(datetime(2020, 9, 17, 1, 0)), LOCAL_TZ.localize(datetime(2020, 9, 18, 0, 0), False) + result, + LOCAL_TZ.localize(datetime(2020, 9, 17, 1, 0)), + LOCAL_TZ.localize(datetime(2020, 9, 18, 0, 0), False), + qh=False ) with it('gets 25 registers for a p48cierre xml file from October saving time day'): @@ -149,7 +158,10 @@ def validate_data(result, start, end, cierre=None): validate_json(result) validate_data( - result, LOCAL_TZ.localize(datetime(2019, 10, 27, 1, 0)), LOCAL_TZ.localize(datetime(2019, 10, 28, 0, 0)), True + result, + LOCAL_TZ.localize(datetime(2019, 10, 27, 1, 0)), + LOCAL_TZ.localize(datetime(2019, 10, 28, 0, 0)), True, + qh=False ) data = json.loads(result) expect(len(data)).to(equal(25)) @@ -160,7 +172,10 @@ def validate_data(result, start, end, cierre=None): validate_json(result) validate_data( - result, LOCAL_TZ.localize(datetime(2020, 3, 29, 1, 0)), LOCAL_TZ.localize(datetime(2020, 3, 30, 0, 0)), True + result, + LOCAL_TZ.localize(datetime(2020, 3, 29, 1, 0)), + LOCAL_TZ.localize(datetime(2020, 3, 30, 0, 0)), True, + qh=False ) data = json.loads(result) From 60ac370368e6f47f1892fd55e01135b867df1146 Mon Sep 17 00:00:00 2001 From: davidmunoznovoa Date: Wed, 10 Dec 2025 13:33:04 +0100 Subject: [PATCH 3/4] Add tipo_unidad and unidad_medida to p48 parser --- esios/parsers.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/esios/parsers.py b/esios/parsers.py index 01e7f21..0661ffa 100644 --- a/esios/parsers.py +++ b/esios/parsers.py @@ -108,6 +108,19 @@ def parse_cierre(self, content, program_unit): # SeriesTemporales Node st = e[0].getparent() + + # UPEntrada/UPSalida + up_entrada_salida = st[2] + if 'UPEntrada' in up_entrada_salida.tag: + tipo_unidad = 'V' + else: + tipo_unidad = 'C' + + # UnidadMedida + up_unidad_medida = st[3] + if 'UnidadMedida' in up_unidad_medida.tag: + unidad_medida = up_unidad_medida.get('v') + # Periodo periodo = st[4] # Curve: @@ -134,7 +147,9 @@ def parse_cierre(self, content, program_unit): 'utc_timestamp': utc_timestamp, 'local_timestamp': local_timestamp, 'cierre': is_cierre, - 'type': integrity + 'type': integrity, + 'tipo_unidad': tipo_unidad, + 'unidad_medida': unidad_medida }) return curve From 8e4da207ffddaf28d09e0019f4e56d4ae4f5f9e1 Mon Sep 17 00:00:00 2001 From: davidmunoznovoa Date: Wed, 10 Dec 2025 17:31:13 +0100 Subject: [PATCH 4/4] Fix test for current P48 --- spec/parsers_spec.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/parsers_spec.py b/spec/parsers_spec.py index 29a9c2d..88cd804 100644 --- a/spec/parsers_spec.py +++ b/spec/parsers_spec.py @@ -83,10 +83,10 @@ def validate_data(result, start, end, cierre=None, qh=True): today = datetime.now() start = LOCAL_TZ.localize( - today.replace(hour=0, minute=0, second=0, microsecond=0) - relativedelta(days=1) + today.replace(hour=0, minute=0, second=0, microsecond=0) - relativedelta(days=2) ) end = LOCAL_TZ.localize( - today.replace(hour=23, minute=59, second=59, microsecond=0) + today.replace(hour=23, minute=59, second=59, microsecond=0) - relativedelta(days=1) ) result = parser.get_data_json('SOMEC01', start, end)