Proyecto creado

This commit is contained in:
drk0027
2026-01-02 22:33:27 -05:00
commit 9cdeb73247
5 changed files with 400 additions and 0 deletions

180
.gitignore vendored Normal file
View File

@@ -0,0 +1,180 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
#archivos para este proyecto
*.pdf
*.csv
*.json

18
LICENSE Normal file
View File

@@ -0,0 +1,18 @@
MIT License
Copyright (c) 2026 Drk0027
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

99
README.md Normal file
View File

@@ -0,0 +1,99 @@
# Consumo Eléctrico - Extractor y Analizador
Este proyecto permite **extraer automáticamente datos de consumo eléctrico** desde planillas de luz en formato PDF (texto digital), organizarlos en tablas y exportarlos a **CSV y JSON** para análisis y visualización.
## Características
- Extrae el **Valor total** desde la fila `VALOR TOTAL` en la columna `Valor total`.
- Obtiene también la **fecha** de cada planilla.
- Exporta resultados a:
- `consumo.csv` → tabla lista para abrir en Excel o LibreOffice.
- `consumo.json` → formato estructurado para integraciones o APIs.
- Genera gráficos comparativos:
- Evolución mensual del consumo.
- Comparación entre el último año y el anterior.
- Etiquetas con valores exactos en cada punto. (mas o menos)
## Ejemplo de salida
**CSV (`consumo.csv`):**
```csv
archivo,Fecha,KW Consumidos,Valor total,Valor SE y AP,Valor Basura
enero-2024.pdf,10-01-2024,679.00,94.98,86.37,6.31
febrero-2024.pdf,08-02-2024,619.00,86.62,78.58,5.74
marzo-2024.pdf,11-03-2024,604.00,84.53,76.63,5.6
```
**JSON (`consumo.json`):**
```
[
{
"archivo":"enero-2024.pdf",
"Fecha":"10-01-2024",
"KW Consumidos":"679.00",
"Valor total":94.98,
"Valor SE y AP":86.37,
"Valor Basura":6.31
},
{
"archivo":"febrero-2024.pdf",
"Fecha":"08-02-2024",
"KW Consumidos":"619.00",
"Valor total":86.62,
"Valor SE y AP":78.58,
"Valor Basura":5.74
},
]
```
**Gráfico comparativo:**
- Línea azul → último año.
- Línea roja → año anterior.
- Etiquetas con valores de consumo en cada mes.
## Instalación
1. Clona este repositorio:
```bash
git clone https://git.interlan.ec/Drk0027/consumo-electrico.git
cd consumo-electrico
```
2. Instala dependencias:
```bash
pip install -r requirements.txt
```
Dependencias principales:
- `pdfplumber`
- `pandas`
- `matplotlib`
## Uso
1. Coloca tus archivos PDF en la carpeta con nombres en formato `nombremes-año.pdf`.
2. Edita `main.py` en la fila 7, con los nombres de tus archivos pdf.
3. Ejecuta el script principal:
```bash
python extraer_consumo.py
```
4. Revisa los archivos generados:
- `consumo.csv`
- `consumo.json`
- Gráficos en pantalla o exportados como imágenes.
## 💡 Ideas de mejora
- Extracción de **costo total** y otros campos (tarifa, número de medidor).
- ¿Alguna forma de automatizacion para descargar regularmente las facturas que llegan al correo?
- Mas Flexibilidad para no tener que agregar los archivos de forma manual.
## 📬 Sugerencias y contacto
Me encantaría recibir tus ideas y mejoras.
Puedes escribirme a:
- 📧 **Correo:** `drk0027@interlan.ec`
- 📢 **Canal de Telegram:** [t.me/drk0072](https://t.me/drk0072)
---
¡Gracias por usar este proyecto! Tu retroalimentación ayuda a que siga creciendo.

92
main.py Normal file
View File

@@ -0,0 +1,92 @@
import pdfplumber
import re
import pandas as pd
import matplotlib.pyplot as plt
archivos = ["enero-2024.pdf", "febrero-2024.pdf", "marzo-2024.pdf","abril-2024.pdf","junio-2024.pdf","julio-2024.pdf","agosto-2024.pdf","septiembre-2024.pdf","octubre-2024.pdf","noviembre-2024.pdf","diciembre-2024.pdf","enero-2025.pdf", "febrero-2025.pdf", "marzo-2025.pdf","abril-2025.pdf","junio-2025.pdf","julio-2025.pdf","agosto-2025.pdf","septiembre-2025.pdf","octubre-2025.pdf","noviembre-2025.pdf","diciembre-2025.pdf"]
datos = []
for archivo in archivos:
with pdfplumber.open(archivo) as pdf:
texto = " ".join([p.extract_text() for p in pdf.pages if p.extract_text()])
#print(texto)
# Patrones
fecha = re.search(r"Fecha hasta *?(\d{2}-\d{2}-\d{4})", texto)
consumo = re.search(r"Consumo.*?(\d+)\s*kWh", texto)
total = re.search(r"VALOR TOTAL.*?\$?([\d,.]+)", texto)
val_imp = re.search(r"TOTAL SE Y AP \(1\).*?\$?([\d,.]+)", texto)
val_basura = re.search(r"TOTAL RECOLECCIÓN BASURA \(5\).*?\$?([\d,.]+)", texto)
#print(fecha)
for pagina in pdf.pages:
tablas = pagina.extract_tables()
for tabla in tablas:
df_tabla = pd.DataFrame(tabla[1:], columns=tabla[0])
# Buscar la fila específica
fila = df_tabla[df_tabla.iloc[:,0].str.contains("Energía Facturada", case=False, na=False)]
if not fila.empty:
consumo = fila["Consumo Total"].values[0] # nombre exacto de la columna
datos.append({
"archivo": archivo,
"Fecha" : fecha.group(1) if fecha else None,
"KW Consumidos": consumo,
"Valor total": float(total.group(1).replace(",", "")) if total else None,
"Valor SE y AP": float(val_imp.group(1).replace(",", "")) if val_imp else None,
"Valor Basura" : float(val_basura.group(1).replace(",", "")) if val_basura else None
})
df = pd.DataFrame(datos)
print(df)
# Exportar a CSV
df.to_csv("consumo.csv", index=False)
# Exportar a JSON
df.to_json("consumo.json", orient="records", indent=4)
print("Datos exportados a consumo.csv y consumo.json")
# aqui grafica los resultados
# Cargar datos
df = pd.read_csv("consumo.csv")
# Convertir fechas
df["Fecha"] = pd.to_datetime(df["Fecha"], dayfirst=True)
df["anio"] = df["Fecha"].dt.year
df["mes"] = df["Fecha"].dt.month
# Identificar último año y anterior
ultimo_anio = df["anio"].max()
anterior_anio = ultimo_anio - 1
# Filtrar datos
df_ultimo = df[df["anio"] == ultimo_anio]
df_anterior = df[df["anio"] == anterior_anio]
# Graficar comparación
plt.figure(figsize=(10,6))
plt.plot(df_anterior["mes"], df_anterior["KW Consumidos"], marker="o", label=f"Año {anterior_anio}", color="red")
plt.plot(df_ultimo["mes"], df_ultimo["KW Consumidos"], marker="o", label=f"Año {ultimo_anio}", color="blue")
# etiquetas a los valores
for x, y in zip(df_anterior["mes"], df_anterior["Valor total"]):
plt.text(x, y+5, str(y), color="red", ha="center", fontsize=8)
for x, y in zip(df_ultimo["mes"], df_ultimo["Valor total"]):
plt.text(x, y+5, str(y), color="blue", ha="center", fontsize=8)
plt.title("Comparación de consumo eléctrico entre dos años")
plt.xlabel("Mes")
plt.ylabel("Consumo Total (kWh)")
plt.xticks(range(1,13))
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

11
requirements.txt Normal file
View File

@@ -0,0 +1,11 @@
matplotlib==3.9.2
multidict==6.1.0
numpy==2.1.2
pandas==2.2.3
pdfminer.six==20251107
pdfplumber==0.11.8
pillow==11.0.0
plotly==5.24.1
python-dateutil==2.9.0.post0
pytz==2024.2
tzdata==2024.2