From 4581102eeb7347bec9629ce4c5144e9d14f01da0 Mon Sep 17 00:00:00 2001 From: davidmunoznovoa Date: Wed, 24 May 2023 13:19:57 +0200 Subject: [PATCH] Implemented MAGCL and MAGCLQH --- README.md | 2 + mesures/headers.py | 24 ++++++++++ mesures/magcl.py | 116 +++++++++++++++++++++++++++++++++++++++++++++ mesures/magclqh.py | 30 ++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 mesures/magcl.py create mode 100644 mesures/magclqh.py diff --git a/README.md b/README.md index 72a19d7..c6384b3 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ - `F3` - `F5` - `F5D` +- `MAGCL` +- `MAGCLQH` - `MCIL345` - `MEDIDAS` - `P1` diff --git a/mesures/headers.py b/mesures/headers.py index 4327dfe..dbace64 100644 --- a/mesures/headers.py +++ b/mesures/headers.py @@ -313,6 +313,30 @@ 'factura' # str ] +MAGCL_HEADER = [ + 'distribuidora', # str(4) + 'comercialitzadora', # str(4) + 'agree_tensio', # str(2) + 'agree_tarifa', # str(2) + 'agree_dh', # str(2) + 'agree_tipo', # str(2) + 'provincia', # str(2) + 'tipus_demanda', # str(2) + 'timestamp', # str(aaaa/mm/dd hh:mm) + 'estacio', # str(1) in ('0' for winter, '1' for summer) + 'magnitud', # str(2) + 'consum', # int(10) + 'n_punts', # int(7) + 'm_iec_real', # int(10) + 'n_iec_real', # int(7) + 'm_iec_estimada', # int(10) + 'n_iec_estimada', # int(7) + 'm_integrats_real', # int(10) + 'n_integrats_real', # int(7) + 'm_integrats_estimada', # int(10) + 'n_integrats_estimada' # int(7) +] + MCIL345_HEADER = [ 'cil', # str(25) CUPS + 3 digits ('001' style) 'timestamp', # str(aaaa/mm/dd hh) diff --git a/mesures/magcl.py b/mesures/magcl.py new file mode 100644 index 0000000..6775b29 --- /dev/null +++ b/mesures/magcl.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +from mesures.dates import * +from mesures.headers import MAGCL_HEADER as COLUMNS +from mesures.parsers.dummy_data import DummyCurve +from mesures.utils import check_line_terminator_param +import os +import pandas as pd + + +class MAGCL(object): + def __init__(self, data, distributor=None, compression='bz2', columns=COLUMNS, version=0): + """ + :param data: list of dicts or absolute file_path + :param distributor: str distributor REE code + :param compression: 'bz2', 'gz'... OR False otherwise + """ + if isinstance(data, list): + data = DummyCurve(data).curve_data + self.columns = columns + self.file = self.reader(data) + self.generation_date = datetime.now() + self.prefix = 'MAGCL' + self.version = version + self.distributor = distributor + self.default_compression = compression + + def __repr__(self): + return "{}: {} kWh".format(self.filename, self.total) + + def __gt__(self, other): + return self.total > other.total + + def __lt__(self, other): + return self.total < other.total + + def __eq__(self, other): + return self.file.equals(other.file) + + def __add__(self, other): + return self.file.append(other.file) + + def __len__(self): + return len(self.file) + + @property + def filename(self): + filename = "{prefix}_{distributor}_{measures_date}_{timestamp}.{version}".format( + prefix=self.prefix, distributor=self.distributor, + measures_date=self.measures_date[:10].replace('/', ''), + timestamp=self.generation_date.strftime(SIMPLE_DATE_MASK), version=self.version + ) + if self.default_compression: + filename += ".{compression}".format(compression=self.default_compression) + + return filename + + @property + def total(self): + return float(self.file[self.file['magnitud' == 'AE']]['consum'].sum()) + + @property + def ai(self): + return float(self.file[self.file['magnitud' == 'AE']]['consum'].sum()) + + @property + def ae(self): + return float(self.file[self.file['magnitud' == 'AS']]['consum'].sum()) + + @property + def r1(self): + return float(self.file[self.file['magnitud' == 'R1']]['consum'].sum()) + + @property + def r2(self): + return float(self.file[self.file['magnitud' == 'R2']]['consum'].sum()) + + @property + def r3(self): + return float(self.file[self.file['magnitud' == 'R3']]['consum'].sum()) + + @property + def r4(self): + return float(self.file[self.file['magnitud' == 'R4']]['consum'].sum()) + + def reader(self, filepath): + if isinstance(filepath, str): + df = pd.read_csv(filepath, sep=';', names=self.columns) + elif isinstance(filepath, list): + df = pd.DataFrame(data=filepath) + else: + raise Exception("Filepath must be an str or a list") + + # TODO data processing + + df = df[self.columns] + return df + + def writer(self): + existing_files = os.listdir('/tmp') + if existing_files: + versions = [int(f.split('.')[1]) for f in existing_files if self.filename.split('.')[0] in f] + if versions: + self.version = max(versions) + 1 + + file_path = os.path.join('/tmp', self.filename) + kwargs = {'sep': ';', + 'header': False, + 'columns': self.columns, + 'index': False, + check_line_terminator_param(): ';\n' + } + if self.default_compression: + kwargs.update({'compression': self.default_compression}) + + self.file.to_csv(file_path, **kwargs) + return file_path diff --git a/mesures/magclqh.py b/mesures/magclqh.py new file mode 100644 index 0000000..9799f54 --- /dev/null +++ b/mesures/magclqh.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from mesures.dates import * +from mesures.headers import MAGCL_HEADER as COLUMNS +from mesures.magcl import MAGCL +import pandas as pd + + +class MAGCLQH(MAGCL): + def __init__(self, data, distributor=None, compression='bz2', columns=COLUMNS, version=0): + """ + :param data: list of dicts or absolute file_path + :param distributor: str distributor REE code + :param compression: 'bz2', 'gz'... OR False otherwise + """ + super(MAGCLQH, self).__init__(data=data, distributor=distributor, compression=compression, columns=columns, + version=version) + self.prefix = 'MAGCLQH' + + def reader(self, filepath): + if isinstance(filepath, str): + df = pd.read_csv(filepath, sep=';', names=self.columns) + elif isinstance(filepath, list): + df = pd.DataFrame(data=filepath) + else: + raise Exception("Filepath must be an str or a list") + + # TODO data processing + + df = df[self.columns] + return df