Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.vscode
main.py
frt_prueba.txt
.idea

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
182 changes: 104 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ Frt00000
Frt00001
```

También se puede consultar por serial de medidor usando la opción `--meter-serial`:

```powershell
> enerbitdso usages fetch --meter-serial "S4AM22060202018" --since 20230401 --until 20230405
```

> **Nota:** `--meter-serial` es mutuamente excluyente con los códigos de frontera (`--frt-file` o argumentos FRTS).

#### Especificación de intervalo de tiempo para la consulta

El intervalo de tiempo se define a través de los parámetros de tipo fecha `--since` y `--until` (desde y hasta, respectivamente).
Expand Down Expand Up @@ -140,150 +148,168 @@ También tiene opción `--help` que muestra la ayuda particular de este sub-coma
│ --frt-file PATH Path file with one frt code per line [default: None] │
│ --connection_timeout INTEGER RANGE The timeout used for HTTP connection in seconds[0<=x<=20][default: 10]│
│ --read_timeout INTEGER RANGE The timeout used for HTTP requests in seconds[60<=x<=120][default: 60]│
│ --meter-serial TEXT Serial del medidor a consultar [default: None] │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```

# Librería DSO

Para poder hacer uso de la librería DSO se debe hacer lo siguiente

## Inicializar el constructor
Para uso programático, `DSOClient` es un cliente asíncrono que debe usarse con `async with` y `await`.

Para ello se debe importar el constructor de la siguiente forma:
## Uso básico

```python
import asyncio
import datetime as dt
from enerbitdso.enerbit import DSOClient
```

La inicialización se debe hacer asi:

```python
ebconnector = DSOClient(
api_base_url="https://dso.enerbit.me/",
api_username="usuario_del_DSO",
api_password="contraseña_del_DSO",
)
```
since = dt.datetime(2023, 4, 1, tzinfo=dt.timezone.utc)
until = dt.datetime(2023, 4, 5, tzinfo=dt.timezone.utc)

Al tener el objeto ya se pueden realizar consultas de la siguiente forma:
async def main():
async with DSOClient(
api_base_url="https://dso.enerbit.me",
api_username="usuario@empresa.com",
api_password="contraseña",
) as client:
records = await client.fetch_schedule_usage_records_large_interval(
frt_code="Frt00000", since=since, until=until
)

```python
usage_records = ebconnector.fetch_schedule_usage_records_large_interval(
frt_code=frt_code, since=since, until=until
)
asyncio.run(main())
```

Tambien se puede hacer una consulta de perfiles de la siguiente forma:
También se puede consultar por serial de medidor:

```python
schedule_records = ebconnector.fetch_schedule_measurements_records_large_interval(
frt_code=frt_code, since=since, until=until
)
async def main():
async with DSOClient(
api_base_url="https://dso.enerbit.me",
api_username="usuario@empresa.com",
api_password="contraseña",
) as client:
records = await client.fetch_schedule_usage_records_large_interval(
meter_serial="S4AM22060202018", since=since, until=until
)
```

## Configuración del Cliente DSO

### Parámetros Básicos
Y para consultar perfiles de medición:

```python
ebconnector = DSOClient(
api_base_url="https://dso.enerbit.me/",
api_username="tu_usuario@empresa.com",
api_password="tu_contraseña"
)
async def main():
async with DSOClient(
api_base_url="https://dso.enerbit.me",
api_username="usuario@empresa.com",
api_password="contraseña",
) as client:
schedule_records = await client.fetch_schedule_measurements_records_large_interval(
frt_code="Frt00000", since=since, until=until
)
```

### Configuración Avanzada con Timeouts
## Parámetros de timeout

Para mejorar la estabilidad en consultas masivas, especialmente cuando se procesan muchas fronteras, se recomienda configurar timeouts personalizados:
Para mejorar la estabilidad en consultas masivas se pueden configurar timeouts personalizados:

```python
ebconnector = DSOClient(
api_base_url="https://dso.enerbit.me/",
async with DSOClient(
api_base_url="https://dso.enerbit.me",
api_username="tu_usuario@empresa.com",
api_password="tu_contraseña",
connection_timeout=20, # Timeout de conexión en segundos (1-60)
read_timeout=120 # Timeout de lectura en segundos (60-300)
)
connection_timeout=20, # Timeout de conexión en segundos (0-20, default: 10)
read_timeout=120 # Timeout de lectura en segundos (60-120, default: 60)
) as client:
...
```

### Parámetros de Timeout

- **connection_timeout**: Tiempo máximo para establecer conexión con el servidor (recomendado: 10-30 segundos)
- **read_timeout**: Tiempo máximo para recibir respuesta del servidor (recomendado: 60-180 segundos)

### Configuración con Variables de Entorno
## Variables de entorno para credenciales

Una práctica recomendada es usar variables de entorno para las credenciales:

```python
import asyncio
import os
from enerbitdso.enerbit import DSOClient

ebconnector = DSOClient(
api_base_url=os.getenv("DSO_HOST", "https://dso.enerbit.me/"),
api_username=os.getenv("DSO_USERNAME"),
api_password=os.getenv("DSO_PASSWORD"),
connection_timeout=20,
read_timeout=120
)
async def main():
async with DSOClient(
api_base_url=os.getenv("DSO_HOST", "https://dso.enerbit.me"),
api_username=os.getenv("DSO_USERNAME"),
api_password=os.getenv("DSO_PASSWORD"),
connection_timeout=20,
read_timeout=120,
) as client:
...

asyncio.run(main())
```

Configurar las variables de entorno:

**Linux/macOS:**
```bash
export DSO_HOST="https://dso.enerbit.me/"
export DSO_HOST="https://dso.enerbit.me"
export DSO_USERNAME="tu_usuario@empresa.com"
export DSO_PASSWORD="tu_contraseña"
```

**Windows:**
```cmd
set DSO_HOST=https://dso.enerbit.me/
set DSO_HOST=https://dso.enerbit.me
set DSO_USERNAME=tu_usuario@empresa.com
set DSO_PASSWORD=tu_contraseña
```

# Ejemplo de Uso Masivo
# Ejemplos

El repositorio incluye dos archivos de ejemplo para distintos casos de uso.

## Archivo `example.py`
## `basic_example.py` — Procesamiento secuencial

El repositorio incluye un archivo `example.py` que demuestra cómo procesar múltiples fronteras de manera eficiente usando concurrencia. Este ejemplo es útil para:
Para uso simple o pocas fronteras. Procesa cada frontera una por una, lo que lo hace fácil de entender y depurar.

- Sin concurrencia
- Sin reintentos automáticos
- Muestra el progreso cada 500 fronteras
- Genera un archivo Excel con matrices horarias de consumo

### Uso:

1. Configurar variables de entorno (como se describe arriba) o editar las constantes `DSO_USER`, `DSO_PASSWORD` y `DSO_BASE_URL` en el script.
2. Crear archivo de fronteras `frt_prueba.txt` con una frontera por línea.
3. Ejecutar:
```bash
python basic_example.py
```

- **Procesamiento masivo de fronteras**: Consulta múltiples fronteras en paralelo
- **Manejo de errores**: Implementa reintentos automáticos y reportes de fronteras fallidas
- **Generación de reportes**: Crea archivos Excel con matrices horarias de consumo
- **Monitoreo de progreso**: Muestra el avance del procesamiento cada 500 fronteras
## `concurrent_example.py` — Procesamiento concurrente

### Características del ejemplo:
Para procesamiento masivo (cientos o miles de fronteras). Lanza todas las consultas en paralelo con un límite de concurrencia.

- 🚀 **Concurrencia**: Usa ThreadPoolExecutor para procesar múltiples fronteras simultáneamente
- 🔄 **Reintentos**: Implementa backoff exponencial para manejar errores de red
- 📊 **Progreso visual**: Muestra estadísticas de avance durante la ejecución
- 📈 **Salida estructurada**: Genera matrices Excel organizadas por hora, día, mes y año
- ⚠️ **Manejo de errores**: Reporta fronteras fallidas para análisis posterior
- Usa `asyncio.Semaphore(5)` para limitar la concurrencia máxima a 5 solicitudes simultáneas
- Reintentos con backoff exponencial (hasta 3 intentos por frontera)
- Monitoreo de progreso cada 500 fronteras
- Genera un archivo Excel con matrices horarias de consumo

### Uso del ejemplo:
### Uso:

1. **Configurar variables de entorno** (como se describe arriba)
2. **Crear archivo de fronteras**: `frt_prueba.txt` con una frontera por línea
3. **Ejecutar el script**:
1. Configurar variables de entorno o editar las constantes en el script.
2. Crear archivo de fronteras `frt_prueba.txt` con una frontera por línea.
3. Ejecutar:
```bash
python example.py
python concurrent_example.py
```

### Archivos generados:
### Archivos generados por ambos ejemplos:

- `Matrices_YYYYMMDD_HHMM.xlsx` - Datos principales organizados por matrices horarias
- `fronteras_fallidas_YYYYMMDD_HHMM.txt` - Lista de fronteras que no se pudieron procesar
- `Matrices_YYYYMMDD_HHMM.xlsx` Datos principales organizados por matrices horarias
- `fronteras_fallidas_YYYYMMDD_HHMM.txt` Lista de fronteras que no se pudieron procesar

### Configuración recomendada para producción:

Para ambientes de producción o consultas masivas, ajusta estos parámetros en el ejemplo:

- **max_workers**: Reduce de 30 a 5-10 para evitar saturar el servidor
- **semaphore**: Límite de conexiones concurrentes. Reduce de 30 a 5-10 para evitar saturar el servidor
- **Timeouts**: Usa connection_timeout=20 y read_timeout=120 como mínimo
- **Intervalos de tiempo**: Limita los rangos de fechas para consultas más eficientes

El archivo `example.py` sirve como base para desarrollar tus propios scripts de procesamiento masivo de datos de enerBit DSO.
Los archivos `*_example.py` sirve como base para desarrollar tus propios scripts de procesamiento masivo de datos de enerBit DSO.
Loading
Loading