orgm-bt 0.4.0__tar.gz

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.
Files changed (128) hide show
  1. orgm_bt-0.4.0/MANIFEST.in +9 -0
  2. orgm_bt-0.4.0/PKG-INFO +634 -0
  3. orgm_bt-0.4.0/README.md +597 -0
  4. orgm_bt-0.4.0/app/__init__.py +10 -0
  5. orgm_bt-0.4.0/app/adapters/__init__.py +1 -0
  6. orgm_bt-0.4.0/app/api.py +607 -0
  7. orgm_bt-0.4.0/app/api_models.py +189 -0
  8. orgm_bt-0.4.0/app/cli.py +522 -0
  9. orgm_bt-0.4.0/app/config.py +96 -0
  10. orgm_bt-0.4.0/app/db/__init__.py +3 -0
  11. orgm_bt-0.4.0/app/db/alembic/env.py +95 -0
  12. orgm_bt-0.4.0/app/db/alembic/versions/20250101000000_create_calc_api_tables.py +212 -0
  13. orgm_bt-0.4.0/app/db/alembic/versions/90c3cdb1d7d5_create_empresas_and_proyectos_tables.py +56 -0
  14. orgm_bt-0.4.0/app/db/alembic/versions/c6020725a319_seed_default_empresa_orgm.py +54 -0
  15. orgm_bt-0.4.0/app/db/database.py +31 -0
  16. orgm_bt-0.4.0/app/db/models.py +46 -0
  17. orgm_bt-0.4.0/app/default_assets/memoria.svg +72 -0
  18. orgm_bt-0.4.0/app/default_data/CEPM.json +1 -0
  19. orgm_bt-0.4.0/app/default_data/MOPC.json +6242 -0
  20. orgm_bt-0.4.0/app/default_data/NEC.json +1 -0
  21. orgm_bt-0.4.0/app/default_data/aires_predeterminados.json +806 -0
  22. orgm_bt-0.4.0/app/default_data/breakers.json +24 -0
  23. orgm_bt-0.4.0/app/default_data/cargas_predeterminadas.json +821 -0
  24. orgm_bt-0.4.0/app/default_data/categorias.json +10 -0
  25. orgm_bt-0.4.0/app/default_data/circuitos_panel.json +52 -0
  26. orgm_bt-0.4.0/app/default_data/conexiones_cables.json +190 -0
  27. orgm_bt-0.4.0/app/default_data/estimacion_area.json +216 -0
  28. orgm_bt-0.4.0/app/default_data/factores_demanda.json +961 -0
  29. orgm_bt-0.4.0/app/default_data/motores_predeterminados.json +1055 -0
  30. orgm_bt-0.4.0/app/default_data/nec_250_66.json +101 -0
  31. orgm_bt-0.4.0/app/default_data/nema.json +36 -0
  32. orgm_bt-0.4.0/app/default_data/norma.json +65 -0
  33. orgm_bt-0.4.0/app/default_data/panel.json +178 -0
  34. orgm_bt-0.4.0/app/default_data/proposito.json +21 -0
  35. orgm_bt-0.4.0/app/du/alimentador.py +576 -0
  36. orgm_bt-0.4.0/app/du/dibujante.py +400 -0
  37. orgm_bt-0.4.0/app/du/du.py +997 -0
  38. orgm_bt-0.4.0/app/du/du_json.py +433 -0
  39. orgm_bt-0.4.0/app/importers/__init__.py +1 -0
  40. orgm_bt-0.4.0/app/importers/csv_paneles.py +308 -0
  41. orgm_bt-0.4.0/app/importers/csv_parser.py +156 -0
  42. orgm_bt-0.4.0/app/importers/entity_detector.py +242 -0
  43. orgm_bt-0.4.0/app/importers/errors.py +235 -0
  44. orgm_bt-0.4.0/app/importers/hierarchy_builder.py +181 -0
  45. orgm_bt-0.4.0/app/importers/mapping.py +213 -0
  46. orgm_bt-0.4.0/app/local_config.py +94 -0
  47. orgm_bt-0.4.0/app/models.py +105 -0
  48. orgm_bt-0.4.0/app/paneles_editor.py +1789 -0
  49. orgm_bt-0.4.0/app/runtime_paths.py +43 -0
  50. orgm_bt-0.4.0/app/schemas.py +73 -0
  51. orgm_bt-0.4.0/app/services/__init__.py +3 -0
  52. orgm_bt-0.4.0/app/services/generador_pdf.py +6363 -0
  53. orgm_bt-0.4.0/app/services/job_store.py +537 -0
  54. orgm_bt-0.4.0/app/services/job_worker.py +457 -0
  55. orgm_bt-0.4.0/app/services/local_operations.py +594 -0
  56. orgm_bt-0.4.0/app/services/logo_url.py +83 -0
  57. orgm_bt-0.4.0/app/services/project_store.py +301 -0
  58. orgm_bt-0.4.0/app/services/redaction.py +42 -0
  59. orgm_bt-0.4.0/app/services/remote_operations.py +445 -0
  60. orgm_bt-0.4.0/app/services/validator.py +365 -0
  61. orgm_bt-0.4.0/app/services/webdav_storage.py +277 -0
  62. orgm_bt-0.4.0/app/static/css/templates/alimentadores.css +76 -0
  63. orgm_bt-0.4.0/app/static/css/templates/cuadros-base.css +242 -0
  64. orgm_bt-0.4.0/app/static/css/templates/electrodo.css +105 -0
  65. orgm_bt-0.4.0/app/static/css/templates/equipos.css +117 -0
  66. orgm_bt-0.4.0/app/static/css/templates/memoria.css +369 -0
  67. orgm_bt-0.4.0/app/static/css/templates/menu.css +127 -0
  68. orgm_bt-0.4.0/app/static/css/templates/mpm.css +148 -0
  69. orgm_bt-0.4.0/app/static/css/templates/paneles.css +140 -0
  70. orgm_bt-0.4.0/app/static/css/templates/print-content.css +74 -0
  71. orgm_bt-0.4.0/app/static/css/templates/print-menu.css +38 -0
  72. orgm_bt-0.4.0/app/static/css/templates/reportes-common.css +104 -0
  73. orgm_bt-0.4.0/app/static/css/templates/trf.css +211 -0
  74. orgm_bt-0.4.0/app/static/js/menu-reportes.js +261 -0
  75. orgm_bt-0.4.0/app/templates/memoria-calculo.html +556 -0
  76. orgm_bt-0.4.0/app/templates/menu.html +40 -0
  77. orgm_bt-0.4.0/app/templates/template-alimentadores.html +91 -0
  78. orgm_bt-0.4.0/app/templates/template-cuadro-distribucion.html +334 -0
  79. orgm_bt-0.4.0/app/templates/template-electrodo.html +66 -0
  80. orgm_bt-0.4.0/app/templates/template-equipos.html +491 -0
  81. orgm_bt-0.4.0/app/templates/template-memoria.html +2378 -0
  82. orgm_bt-0.4.0/app/templates/template-mpm.html +248 -0
  83. orgm_bt-0.4.0/app/templates/template-paneles.html +101 -0
  84. orgm_bt-0.4.0/app/templates/template-trf-standalone.html +89 -0
  85. orgm_bt-0.4.0/app/templates/template-trf.html +604 -0
  86. orgm_bt-0.4.0/app/utils/__init__.py +1 -0
  87. orgm_bt-0.4.0/app/utils/aireacondicionado.py +57 -0
  88. orgm_bt-0.4.0/app/utils/cables.py +2053 -0
  89. orgm_bt-0.4.0/app/utils/carga.py +1897 -0
  90. orgm_bt-0.4.0/app/utils/chromium_pdf.py +226 -0
  91. orgm_bt-0.4.0/app/utils/circuitos.py +489 -0
  92. orgm_bt-0.4.0/app/utils/comercio.py +28 -0
  93. orgm_bt-0.4.0/app/utils/conduit_rules.py +178 -0
  94. orgm_bt-0.4.0/app/utils/device_type_catalog.py +231 -0
  95. orgm_bt-0.4.0/app/utils/electrodo.py +503 -0
  96. orgm_bt-0.4.0/app/utils/equipos.py +1421 -0
  97. orgm_bt-0.4.0/app/utils/factores_demanda.py +362 -0
  98. orgm_bt-0.4.0/app/utils/firma.py +116 -0
  99. orgm_bt-0.4.0/app/utils/load_semantics.py +53 -0
  100. orgm_bt-0.4.0/app/utils/logger.py +296 -0
  101. orgm_bt-0.4.0/app/utils/motores.py +69 -0
  102. orgm_bt-0.4.0/app/utils/mpm.py +1504 -0
  103. orgm_bt-0.4.0/app/utils/norma.py +331 -0
  104. orgm_bt-0.4.0/app/utils/panel.py +4024 -0
  105. orgm_bt-0.4.0/app/utils/pdf_output.py +45 -0
  106. orgm_bt-0.4.0/app/utils/print_pdf.py +122 -0
  107. orgm_bt-0.4.0/app/utils/residencial.py +565 -0
  108. orgm_bt-0.4.0/app/utils/tablas.py +447 -0
  109. orgm_bt-0.4.0/app/utils/trf.py +1690 -0
  110. orgm_bt-0.4.0/app/utils/weasyprint_fetcher.py +89 -0
  111. orgm_bt-0.4.0/app/utils/weasyprint_pdf.py +96 -0
  112. orgm_bt-0.4.0/app/validators/__init__.py +1 -0
  113. orgm_bt-0.4.0/app/validators/paneles_integrity.py +245 -0
  114. orgm_bt-0.4.0/app/validators/paneles_schema.py +384 -0
  115. orgm_bt-0.4.0/app/validators/paneles_validator.py +194 -0
  116. orgm_bt-0.4.0/app/workspace.py +543 -0
  117. orgm_bt-0.4.0/local.py +998 -0
  118. orgm_bt-0.4.0/main.py +2904 -0
  119. orgm_bt-0.4.0/orgm_bt.egg-info/PKG-INFO +634 -0
  120. orgm_bt-0.4.0/orgm_bt.egg-info/SOURCES.txt +126 -0
  121. orgm_bt-0.4.0/orgm_bt.egg-info/dependency_links.txt +1 -0
  122. orgm_bt-0.4.0/orgm_bt.egg-info/entry_points.txt +2 -0
  123. orgm_bt-0.4.0/orgm_bt.egg-info/requires.txt +23 -0
  124. orgm_bt-0.4.0/orgm_bt.egg-info/top_level.txt +4 -0
  125. orgm_bt-0.4.0/pyproject.toml +73 -0
  126. orgm_bt-0.4.0/setup.cfg +4 -0
  127. orgm_bt-0.4.0/storage/__init__.py +3 -0
  128. orgm_bt-0.4.0/storage/s3.py +191 -0
@@ -0,0 +1,9 @@
1
+ # Never publish local identities, credentials, or project catalogs.
2
+ exclude F_OSMAR.png
3
+ exclude app/default_assets/F_OSMAR.png
4
+ exclude app/default_assets/CODIA.jpeg
5
+ prune datos
6
+ prune logs
7
+ prune temp
8
+ prune tests
9
+ global-exclude .env .env.* *.pyc __pycache__
orgm_bt-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,634 @@
1
+ Metadata-Version: 2.4
2
+ Name: orgm-bt
3
+ Version: 0.4.0
4
+ Summary: CLI for low-voltage electrical calculations, panel schedules, and HTML/PDF reports
5
+ Project-URL: Repository, https://github.com/osmargm1202/calc
6
+ Project-URL: Issues, https://github.com/osmargm1202/calc/issues
7
+ Keywords: electrical,low-voltage,NEC,panel-schedules,cli
8
+ Classifier: Environment :: Console
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Topic :: Scientific/Engineering
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: jinja2>=3.1.0
15
+ Requires-Dist: weasyprint>=60.0
16
+ Requires-Dist: pillow>=11.0.0
17
+ Requires-Dist: reportlab>=4.4.4
18
+ Requires-Dist: sqlmodel>=0.0.14
19
+ Requires-Dist: alembic>=1.13.0
20
+ Requires-Dist: psycopg2-binary>=2.9.9
21
+ Requires-Dist: pydantic-settings>=2.0.0
22
+ Requires-Dist: fastapi>=0.109.0
23
+ Requires-Dist: uvicorn[standard]>=0.27.0
24
+ Requires-Dist: requests>=2.32.5
25
+ Requires-Dist: python-dotenv>=1.0.1
26
+ Requires-Dist: pandas>=2.0.0
27
+ Requires-Dist: boto3>=1.34.0
28
+ Requires-Dist: rich>=13.9.4
29
+ Requires-Dist: tabulate>=0.9.0
30
+ Requires-Dist: nocodb>=2.0.1
31
+ Requires-Dist: questionary>=2.0.1
32
+ Requires-Dist: coloraide>=5.1
33
+ Requires-Dist: hsluv>=5.0.4
34
+ Requires-Dist: python-multipart>=0.0.20
35
+ Requires-Dist: customtkinter>=5.2.2
36
+ Requires-Dist: webdav4==0.11.0
37
+
38
+ # orgm-bt: Electrical Calculation Library
39
+
40
+ A Python library for electrical load calculations and balancing according to NEC standards. This library provides tools for importing AutoCAD data, calculating load balances, and generating PDF reports.
41
+
42
+ ## uv
43
+
44
+ uv venv --directory /home/osmar/Code/calc
45
+ export UV_PROJECT_ENVIRONMENT=/home/osmar/Code/calc/.venv
46
+ export VIRTUAL_ENV=/home/osmar/Code/calc/.venv
47
+
48
+
49
+ ## Features
50
+
51
+ - **Data Import**: Parse AutoCAD TXT files for circuits, CSV files for panels, and DU files for diagramas unifilares
52
+ - **Load Balancing**: Greedy algorithm for optimal circuit-to-phase assignment
53
+ - **Code Validation**: Support for predefined load codes with automatic normalization
54
+ - **Custom Loads**: Handle custom format codes (M-208-3F-5HP, AC-480-3F-10KVA)
55
+ - **Load Calculation**: Complete electrical load calculations according to NEC standards
56
+ - **Panel Hierarchy**: Automatic detection and validation of panel hierarchies (TRF → MPM → Panels)
57
+ - **PDF Generation**: Generate professional reports using WeasyPrint with multiple document types:
58
+ - Memoria de cálculo
59
+ - Cuadros de distribución
60
+ - Alimentadores
61
+ - Módulos MPM
62
+ - Transformadores (TRF)
63
+ - Equipos especiales
64
+ - **DU Processing**: Process and enrich Diagrama Unifilar (DU) files with calculated feeder data
65
+ - **Circuit Enrichment**: Enrich circuit files with calculated breaker and cable information
66
+ - **Database Storage**: PostgreSQL with SQLModel for project and company data
67
+ - **Local Command Manager**: Interactive CLI tool (`local.py`) for managing and executing calculation commands
68
+ - **Cloud Storage**: Upload generated files to R2/S3 storage with automatic URL generation
69
+
70
+ ## Installation
71
+
72
+ 1. Clone the repository:
73
+ ```bash
74
+ git clone <repository-url>
75
+ cd calc
76
+ ```
77
+
78
+ 2. Install dependencies using uv:
79
+ ```bash
80
+ uv sync
81
+ ```
82
+
83
+ 3. Set up environment variables:
84
+ ```bash
85
+ cp .env.example .env
86
+ # Edit .env with your database connection details
87
+ ```
88
+
89
+ 4. Set up the database:
90
+ ```bash
91
+ uv run alembic upgrade head
92
+ ```
93
+
94
+ ## Quick Start
95
+
96
+ ### 1. CLI local instalable
97
+
98
+ La CLI no usa una ruta por defecto: no ejecuta cálculos hasta que el operador
99
+ configure explícitamente los activos y la carpeta de proyectos. Instálela con `uv tool`:
100
+
101
+ ```bash
102
+ # Cuando la versión esté publicada en PyPI:
103
+ pip install orgm-bt
104
+ #
105
+ # Alternativa desde el repositorio:
106
+ uv tool install --from git+https://github.com/osmargm1202/calc.git orgm-bt
107
+
108
+ # Estas rutas son ejemplos: cada PC decide las suyas.
109
+ orgm-bt config setup \
110
+ --assets-dir ~/Documentos/ORGM-Calc/Activos \
111
+ --projects-dir ~/Documentos/ORGM-Calc/Proyectos
112
+ ```
113
+
114
+ La configuración se guarda en `~/.config/orgm-calc/config.json`. `config setup`
115
+ siembra explícitamente los catálogos actuales, `Assets/`, y los perfiles ORGM de
116
+ empresa e ingeniero; no se crea nada hasta proporcionar ambas rutas.
117
+
118
+ `init` no inicializa un workspace. Se ejecuta desde la carpeta donde el agente de
119
+ IA trabajará y crea allí un `AGENTS.md` con el flujo de revisión de CSV, datos
120
+ faltantes, cálculo HTML y PDF:
121
+
122
+ ```bash
123
+ cd ~/Documentos/ORGM-Calc
124
+ orgm-bt init
125
+ ```
126
+
127
+ Cada proyecto guarda solo `ruta`, relativa a `projects_dir`:
128
+
129
+ ```bash
130
+ orgm-bt profile create client acme --name "ACME"
131
+ orgm-bt project create "Nave China" \
132
+ --relative-path "Nave China/Calculos/ELEC" \
133
+ --client acme
134
+ orgm-bt calculate "Nave China/Calculos/ELEC"
135
+ ```
136
+
137
+ El ingeniero es obligatorio y, si se omite `--engineer`, se utiliza el perfil
138
+ configurado. Empresa y cliente son opcionales: sin cliente se muestra la empresa,
139
+ si existe; sin ambos, se dejan vacíos. Para quitar una asignación existente,
140
+ use `project edit RUTA --company "" --client ""`. No se asigna ORGM como empresa
141
+ automáticamente a los proyectos nuevos.
142
+
143
+ Cuando existe el catálogo legado `local.json`, se divide en perfiles y un
144
+ JSON por proyecto en `assets_dir/Proyectos/`, conservando sus opciones de cálculo:
145
+
146
+ ```bash
147
+ orgm-bt project import-local /ruta/anterior/datos/local.json
148
+ ```
149
+
150
+ Sin argumentos, `orgm-bt` abre el menú Questionary: cálculo, DU, PDF, finalizar,
151
+ crear perfiles/proyectos, editar `PANELES.csv`, listar y reconfigurar rutas.
152
+ El cálculo genera HTML primero; PDF es explícito y posterior con WeasyPrint o
153
+ Chromium/Google Chrome headless.
154
+
155
+ ### 2. Uso Directo con main.py
156
+
157
+ Ejecutar cálculos directamente con `main.py`:
158
+
159
+ ```bash
160
+ # Ejemplo básico
161
+ uv run main.py --path /ruta/al/proyecto --output /ruta/salida
162
+
163
+ # Con parámetros adicionales
164
+ uv run main.py \
165
+ --path /ruta/al/proyecto \
166
+ --output /ruta/salida \
167
+ --cliente "Nombre Cliente" \
168
+ --empresa "Nombre Empresa" \
169
+ --ing "Ing. Nombre" \
170
+ --codia "12345" \
171
+ --proyecto-id 1 \
172
+ --url-logo-empresa "https://ejemplo.com/logo.png"
173
+
174
+ # Solo generar HTML (sin PDF)
175
+ uv run main.py --path /ruta/al/proyecto --html
176
+
177
+ # Modo blanco y negro
178
+ uv run main.py --path /ruta/al/proyecto --bn
179
+
180
+ # Especificar tamaños de página personalizados
181
+ uv run main.py \
182
+ --path /ruta/al/proyecto \
183
+ --alimentadores "11,17" \
184
+ --cuadros "36,24" \
185
+ --modulos-trf "24,18"
186
+ ```
187
+
188
+ ### 3. Importar Datos a Base de Datos
189
+
190
+ Create a project and import circuit/panel data:
191
+
192
+ ```bash
193
+ # Create a new project
194
+ uv run python scripts/import_data.py --create-project "My Project"
195
+
196
+ # Import circuits from TXT file
197
+ uv run python scripts/import_data.py --project-id 1 --import-circuits proy/CIRCUITOS/D\ -\ BT.txt
198
+
199
+ # Import panels from CSV file
200
+ uv run python scripts/import_data.py --project-id 1 --import-panels proy/PANELES/PANELES.csv
201
+ ```
202
+
203
+ ### 4. Estructura de Directorios Requerida
204
+
205
+ El proyecto espera la siguiente estructura en el directorio base (`--path`):
206
+
207
+ ```
208
+ proyecto/
209
+ ├── CIRCUITOS/
210
+ │ └── D - BT.txt # Archivo de circuitos (TXT tab-separated)
211
+ ├── PANELES/
212
+ │ └── PANELES.csv # Archivo de paneles (CSV)
213
+ └── DU/
214
+ ├── TRF1.txt # Diagrama del TRF (UTF-8 TSV)
215
+ ├── MPM1.txt # Diagrama de MPM o panel
216
+ ├── TOTALIZADOR-TRF1.txt # Totalizador (DU-facing TTL; interno TOTALIZADOR)
217
+ ├── INV-01.txt # Inversor (DU-facing INV; interno INVERSOR)
218
+ └── ... # Un archivo por equipo (TXT UTF-8)
219
+ ```
220
+
221
+ Los archivos generados se guardan en el directorio de salida especificado con `--output`.
222
+
223
+ ## Scripts Reference
224
+
225
+ ### `scripts/test_calculations.py`
226
+ Comprehensive test script that:
227
+ - Initializes the database
228
+ - Tests individual services (parser, validator, balanceador)
229
+ - Runs complete workflow: import → balance → PDF generation
230
+
231
+ ### `scripts/import_data.py`
232
+ Data import utility with options:
233
+ - `--create-project NAME`: Create new project
234
+ - `--list-projects`: List all projects
235
+ - `--import-circuits FILE`: Import circuits from TXT
236
+ - `--import-panels FILE`: Import panels from CSV
237
+ - `--project-id ID`: Specify project ID
238
+ - `--clear-existing`: Clear existing data before import
239
+
240
+ ### `scripts/generate_pdfs.py`
241
+ PDF generation utility with options:
242
+ - `--list-projects`: List all projects
243
+ - `--project-id ID`: Specify project ID
244
+ - `--output FILE`: Single PDF output file
245
+ - `--output-dir DIR`: Directory for multiple PDFs
246
+ - `--calculate-balance`: Calculate balance before PDF generation
247
+ - `--all-pdfs`: Generate all available PDF types
248
+
249
+ ## Data Formats
250
+
251
+ ### Circuit TXT Format
252
+ Tab-separated values (TSV) file con información de circuitos eléctricos. El archivo puede contener múltiples columnas:
253
+
254
+ **Columnas principales requeridas:**
255
+ - `HANDLE`: Identificador único del circuito
256
+ - `BLOCKNAME`: Nombre del bloque (generalmente "BT - CIRCUITO")
257
+ - `PANEL`: Nombre del panel al que pertenece el circuito
258
+ - `CANTIDAD`: Cantidad de elementos del circuito
259
+ - `CODIGO` o `CARGA`: Código de carga (TMC, IL, A/A, M-208-3F-5HP, etc.)
260
+ - `AREA`: Área o ubicación del circuito
261
+
262
+ **Columnas opcionales:**
263
+ - `ALIMENTADOR`: Identificador del alimentador
264
+ - `CIRCUITO`: Número de circuito
265
+ - `DISTANCIA`: Distancia en metros
266
+ - `FASE`: Número de fases
267
+ - `POTENCIA`: Potencia en VA/W
268
+ - `FACTOR`: Factor de potencia
269
+ - `TIPO`: Tipo de carga. Use `SERVICIOS_AUXIALIARES` para calcular esa carga a FD=1.
270
+ - `TENSIÓN`: Tensión nominal
271
+ - `CANALIZACION`: Tipo de canalización (`PVC`, `PVC SCH40`, `EMT`, `IMC`, `RMC`, `ENT`)
272
+ - `BREAKER_MINIMO`: Breaker mínimo requerido
273
+ - `CABLE_MINIMO`: Cable mínimo requerido
274
+
275
+ **Columnas custom** (para especificar valores personalizados):
276
+ - `VA_CUSTOM`: Potencia custom en VA
277
+ - `TENSION_CUSTOM`: Tensión custom
278
+ - `FP_CUSTOM`: Factor de potencia custom
279
+ - `FASES_CUSTOM`: Número de fases custom
280
+
281
+ **Ejemplo:**
282
+ ```
283
+ HANDLE BLOCKNAME PANEL CANTIDAD CODIGO AREA ALIMENTADOR CIRCUITO
284
+ '1583E BT - CIRCUITO PBA 6 IL GENERAL
285
+ '158C5 BT - CIRCUITO PBB 5 IL GENERAL
286
+ ```
287
+
288
+ ### Panel CSV Format
289
+ Archivo CSV con información de la jerarquía de paneles y sus características. Define la estructura de alimentación desde transformadores hasta paneles finales.
290
+
291
+ **Columnas requeridas:**
292
+ - `FUENTE`: Panel o transformador origen (TRF, MPM1, MPM2, etc.)
293
+ - `PANEL`: Identificador del panel destino
294
+ - `FASE`: Número de fases (1, 2, 3)
295
+ - `TENSION`: Tensión nominal (120, 208, 240, 277, 480)
296
+
297
+ **Columnas opcionales:**
298
+ - `DISTANCIA`: Distancia en metros desde la fuente
299
+ - `NUMERO`: Número del panel (puede ser rango como "101-102")
300
+ - `AREA`: Área o ubicación del panel
301
+ - `PROPOSITO`: Propósito del panel (residencial, comercial, etc.)
302
+ - `CANALIZACION`: Tipo de canalización (`PVC`, `PVC SCH40`, `EMT`, `IMC`, `RMC`, `ENT`)
303
+ - `TIPO`: Tipo de panel
304
+
305
+ Si la norma del proyecto es **CEPM**, importación desde `PANELES.csv` fuerza `CANALIZACION = PVC SCH40` para todos los alimentadores.
306
+ Importación de `CIRCUITOS`/cargas no aplica ese forzado y preserva el valor proporcionado.
307
+ - `POTENCIA`: Potencia nominal
308
+ - `POTENCIAL`: Potencial eléctrico
309
+ - `NEUTRO`: Configuración de neutro
310
+ - `TIERRA`: Configuración de tierra
311
+
312
+ **Ejemplo:**
313
+ ```
314
+ FUENTE,PANEL,DISTANCIA,NUMERO,FASE,TENSION,AREA,PROPOSITO,CANALIZACION
315
+ MPM3,PBAC,20,1,2,208,AREA COMUN,area comun,EMT
316
+ MPM3,PBS,20,1,2,208,SOTANO,area comun,
317
+ MPM3,PBF,39,101,2,208,BLOQUE A NIVEL 1,residencial,
318
+ ```
319
+
320
+ **Nota:** La jerarquía debe ser válida: TRF → MPM → Paneles. El sistema valida automáticamente que no haya ciclos y que todos los paneles tengan una fuente válida.
321
+
322
+ ### DU (Diagrama Unifilar) TXT Format
323
+ Archivo tab-separated (TSV) UTF-8 para diagramas unifilares.
324
+
325
+ La carpeta `DU/` puede contener **múltiples** archivos `*.txt`. Cada archivo representa un equipo lógico y se procesa de forma independiente al ejecutar `main.py`.
326
+
327
+ **Semántica de nombre de archivo (sin extensión):**
328
+ - `TRF*` → tipo `TRF` (salida tipo resumen/export).
329
+ - `TRFS*`, `MB*`, `MPM*`, `INV*`/`INVERSOR*` → tipo `equipo` (llenado tabular).
330
+ - `TOTALIZADOR*` y `TTL*` → tipo `TTL` (DU-facing; alias interno `TOTALIZADOR*`).
331
+ - cualquier otro prefijo no reconocido → fallback tabular (si existe origen de alimentadores), o `DISPONIBLE` si no.
332
+
333
+ **Columnas requeridas:**
334
+ - `HANDLE`: Identificador único
335
+ - `BLOCKNAME`: Nombre del bloque
336
+ - `DESCRIPCION`: Descripción del elemento
337
+ - `AREA`: Área o ubicación
338
+ - `BREAKER`: Información del breaker (se llena automáticamente)
339
+ - `ALIMENTADOR`: ID del alimentador (se llena automáticamente)
340
+ - `FASE`: Número de fases (se llena automáticamente)
341
+ - `POTENCIAL`: Potencial eléctrico (se llena automáticamente)
342
+ - `PANEL`: Nombre del panel asociado
343
+
344
+ **Ejemplo:**
345
+ ```
346
+ HANDLE BLOCKNAME DESCRIPCION AREA BREAKER ALIMENTADOR FASE POTENCIAL PANEL
347
+ '228AF *U92 - - - TRF1
348
+ '23117 *U93 - - - PBA
349
+ ```
350
+
351
+ **Nota:** Cada archivo generado conserva el nombre original del archivo de entrada bajo el directorio de salida `.../DU/`.
352
+
353
+ ## Load Code Support
354
+
355
+ ### Predefined Codes
356
+ - **TMC**: Tomacorrientes (120V, 1F)
357
+ - **IL**: Iluminación (120V, 1F)
358
+ - **A/A**: Aire acondicionado (208V, 3F)
359
+ - **M2F1**: Motor 2HP (208V, 3F)
360
+
361
+ ### Custom Format Codes
362
+ - **M-208-3F-5HP**: Motor 5HP, 208V, 3-phase
363
+ - **AC-480-3F-10KVA**: AC unit 10KVA, 480V, 3-phase
364
+
365
+ ### Code Normalization
366
+ Automatic normalization with warnings:
367
+ - TMCC → TMC
368
+ - LED → IL
369
+ - LED-P → IL
370
+
371
+ ## Database Schema
372
+
373
+ ### Core Tables
374
+ - `proyectos`: Project information
375
+ - `circuitos`: Circuit data with load information
376
+ - `paneles`: Panel specifications
377
+ - `jerarquia_alimentacion`: Panel hierarchy relationships
378
+
379
+ ### Custom Fields
380
+ - `va_custom`: Custom VA rating
381
+ - `tension_custom`: Custom voltage
382
+ - `fp_custom`: Custom power factor
383
+ - `fases_custom`: Custom phase count
384
+
385
+ ## Configuration Files
386
+
387
+ ### `datos/cargas_predeterminadas.json`
388
+ Predefined load codes with electrical characteristics:
389
+ ```json
390
+ {
391
+ "TMC": {
392
+ "descripcion": "TOMACORRIENTE",
393
+ "potencia": 1800,
394
+ "tension": 120,
395
+ "fase": 1,
396
+ "factor": 1.0,
397
+ "tipo": "tc"
398
+ }
399
+ }
400
+ ```
401
+
402
+ ### `datos/categorias.json`
403
+ Load categories for organization:
404
+ ```json
405
+ {
406
+ "tc": {"nombre": "Tomacorriente", "descripcion": "Tomacorrientes de uso general"},
407
+ "il": {"nombre": "Iluminación", "descripcion": "Iluminación de uso general"},
408
+ "aa": {"nombre": "Aire Acondicionado", "descripcion": "Sistemas de aire acondicionado"}
409
+ }
410
+ ```
411
+
412
+ ## Development
413
+
414
+ ### Project Structure
415
+ ```
416
+ calc/
417
+ ├── app/
418
+ │ ├── utils/ # Utilidades de cálculo
419
+ │ │ ├── carga.py # Conversión y cálculo de cargas
420
+ │ │ ├── circuitos.py # Procesamiento de circuitos
421
+ │ │ ├── panel.py # Gestión de paneles y jerarquías
422
+ │ │ ├── mpm.py # Módulos MPM (Media Power Module)
423
+ │ │ ├── trf.py # Transformadores
424
+ │ │ ├── equipos.py # Equipos especiales (GEN, UPS, etc.)
425
+ │ │ ├── cables.py # Cálculo de cables
426
+ │ │ ├── factores_demanda.py # Factores de demanda
427
+ │ │ └── ... # Otras utilidades
428
+ │ ├── services/ # Servicios principales
429
+ │ │ ├── generador_pdf.py # Generación de PDFs
430
+ │ │ └── validator.py # Validación de datos
431
+ │ ├── du/ # Procesamiento de Diagramas Unifilares
432
+ │ │ ├── du.py # Procesador principal de DU
433
+ │ │ ├── alimentador.py # Lógica de alimentadores
434
+ │ │ └── dibujante.py # Generación de diagramas
435
+ │ ├── db/ # Base de datos
436
+ │ │ ├── models.py # Modelos SQLModel
437
+ │ │ ├── database.py # Conexión a base de datos
438
+ │ │ └── alembic/ # Migraciones Alembic
439
+ │ ├── templates/ # Templates HTML para PDFs
440
+ │ │ ├── template-memoria.html
441
+ │ │ ├── template-cuadro-distribucion.html
442
+ │ │ ├── template-alimentadores.html
443
+ │ │ ├── template-mpm.html
444
+ │ │ ├── template-trf.html
445
+ │ │ ├── template-modulos-mpm-trf.html
446
+ │ │ ├── template-equipos.html
447
+ │ │ └── template-guia-cargas.html
448
+ │ ├── config.py # Configuración de la aplicación
449
+ │ └── __init__.py
450
+ ├── storage/ # Integración con almacenamiento cloud
451
+ │ └── s3.py # Cliente S3/R2
452
+ ├── datos/ # Archivos JSON de configuración
453
+ │ ├── cargas_predeterminadas.json # Códigos de carga
454
+ │ ├── motores_predeterminados.json # Especificaciones de motores
455
+ │ ├── categorias.json # Categorías de cargas
456
+ │ ├── factores_demanda.json # Factores de demanda
457
+ │ ├── nema.json # Estándares NEMA
458
+ │ └── ... # Otros archivos de configuración
459
+ ├── proy/ # Datos de ejemplo
460
+ │ ├── CIRCUITOS/ # Archivos de circuitos
461
+ │ ├── PANELES/ # Archivos de paneles
462
+ │ └── DU/ # Archivos de diagramas unifilares
463
+ ├── temp/ # Directorio temporal para archivos generados
464
+ ├── main.py # Punto de entrada principal
465
+ ├── local.py # Gestor de comandos para uso local
466
+ ├── api.py # API FastAPI (pendiente implementación)
467
+ ├── alembic.ini # Configuración de Alembic
468
+ ├── pyproject.toml # Dependencias y configuración del proyecto
469
+ └── README.md # Este archivo
470
+ ```
471
+
472
+ ### Running Tests
473
+ ```bash
474
+ # Test individual services
475
+ uv run python scripts/test_calculations.py
476
+
477
+ # Test with sample data
478
+ uv run python scripts/import_data.py --create-project "Test" --import-circuits proy/CIRCUITOS/D\ -\ BT.txt
479
+ ```
480
+
481
+ ### Database Migrations
482
+ ```bash
483
+ # Create new migration
484
+ uv run alembic revision --autogenerate -m "Description"
485
+
486
+ # Apply migrations
487
+ uv run alembic upgrade head
488
+ ```
489
+
490
+ ## Requirements
491
+
492
+ - Python 3.11+
493
+ - PostgreSQL 12+
494
+ - uv (package manager)
495
+
496
+ ### Dependencies
497
+ - **PDF Generation**: WeasyPrint, Pillow, ReportLab, svglib
498
+ - **Database**: SQLModel, Alembic, psycopg2-binary, pydantic-settings
499
+ - **API**: FastAPI, uvicorn (pendiente implementación)
500
+ - **Templates**: Jinja2
501
+ - **Cloud Storage**: boto3 (S3/R2)
502
+ - **Utilities**: rich, tabulate, pandas, python-dotenv
503
+ - **Interactive CLI**: questionary
504
+ - **NocoDB**: nocodb (integración opcional)
505
+
506
+ ## License
507
+
508
+ No se ha declarado una licencia de distribución. El titular debe definirla antes
509
+ de anunciar el proyecto como software libre; publicar en PyPI no concede por sí
510
+ solo permisos de reutilización.
511
+
512
+ ## Publicación en PyPI
513
+
514
+ Requiere Python 3.11 o posterior. El editor gráfico necesita Tk/Tcl y una sesión
515
+ gráfica; el PDF con WeasyPrint necesita sus bibliotecas nativas del sistema
516
+ (incluido Pango). Chromium/Chrome es una alternativa externa para PDF.
517
+
518
+ El paquete incluye catálogos de cálculo, plantillas y CSS/JS. No incluye los
519
+ proyectos locales, `.env`, la firma personal ni el carnet CODIA. Cada instalación
520
+ debe aportar esos activos a sus perfiles; los archivos locales existentes no
521
+ se eliminan al instalar o actualizar.
522
+
523
+ Desde la raíz del repositorio, para la versión 0.4.0:
524
+
525
+ ```bash
526
+ uv build
527
+ uvx twine check --strict dist/orgm_bt-0.4.0.tar.gz dist/orgm_bt-0.4.0-py3-none-any.whl
528
+
529
+ # Prueba local del paquete, sin instalar desde el código fuente:
530
+ uv tool install --from ./dist/orgm_bt-0.4.0-py3-none-any.whl orgm-bt
531
+ orgm-bt --help
532
+
533
+ # Publicar solo estos dos artefactos. Requiere autenticación de PyPI.
534
+ # Use UV_PUBLISH_TOKEN desde el entorno; nunca guarde el token en el repositorio.
535
+ uv publish dist/orgm_bt-0.4.0.tar.gz dist/orgm_bt-0.4.0-py3-none-any.whl
536
+ ```
537
+
538
+ Antes de publicar, confirme la licencia y la titularidad del nombre `orgm-bt`
539
+ en PyPI. Para una nueva entrega, incremente `project.version` en `pyproject.toml`,
540
+ ejecute `uv lock` y use los nombres de artefacto de esa versión. PyPI no permite
541
+ reemplazar un archivo ya publicado con el mismo nombre.
542
+
543
+ ## Contributing
544
+
545
+ [Add contribution guidelines here]
546
+
547
+
548
+ ## Workspace local
549
+
550
+ `orgm-bt config setup` prepara los activos y el catálogo central. `orgm-bt init`
551
+ solo escribe la guía del agente en el directorio actual.
552
+
553
+ ```text
554
+ BT/
555
+ ├── Assets/
556
+ ├── Ing/<id>/datos.json, codia.png, firma.png (opcional)
557
+ ├── Empresas/<id>/datos.json, logo.png
558
+ ├── Cliente/<id>/datos.json, logo.png
559
+ ├── Proyectos/<ruta-legible>-<hash>.json
560
+ └── BD/*.json
561
+ ```
562
+
563
+ `BD/` se inicializa con los catálogos incluidos; después es la única base usada por
564
+ los cálculos de ese workspace. Modificar un JSON allí no modifica el programa.
565
+
566
+ Perfiles de ingeniero, empresa y cliente contienen `datos.json`. Campos admitidos:
567
+ `nombre`, `representante`, `correo`, `telefono`, `ubicacion`; el ingeniero añade
568
+ `codia`. Los logos locales se copian al resultado HTML, sin descargarlos de red.
569
+
570
+ Cada JSON de `BT/Proyectos/` persiste la ruta relativa a `projects_dir`.
571
+ CSV, circuitos y resultados permanecen en esa carpeta de cálculo; el CLI no usa
572
+ su `datos.json`, que puede pertenecer a una integración de API. Editar o borrar
573
+ un proyecto afecta al catálogo central, no a sus archivos de cálculo.
574
+
575
+ ```json
576
+ {
577
+ "nombre": "Nave de los Chinos",
578
+ "ruta": "608 - NAVE DE LOS CHINOS/Calculo/ELEC",
579
+ "ingeniero": "osmar",
580
+ "empresa": "",
581
+ "cliente": "cliente-bohc-projects-srl",
582
+ "calculo_realizado": "Memoria de cálculo BT",
583
+ "revision": "R0",
584
+ "descripcion_revision": "Emisión inicial",
585
+ "ubicacion": "Santo Domingo",
586
+ "norma": "MOPC"
587
+ }
588
+ ```
589
+
590
+ ### Flujo terminal
591
+
592
+ ```bash
593
+ # Crear perfiles; copie después logo.png, codia.png o firma.png a sus carpetas.
594
+ orgm-bt profile create engineer osmar --name "Ing. Osmar Garcia" --codia 36467
595
+ orgm-bt profile create client cliente-bohc-projects-srl --name "BOHC PROJECTS SRL"
596
+
597
+ # Crear proyecto y la plantilla PANELES/PANELES.csv.
598
+ orgm-bt project create "Nave de los Chinos" \
599
+ --relative-path "608 - NAVE DE LOS CHINOS/Calculo/ELEC" \
600
+ --engineer osmar --client cliente-bohc-projects-srl --revision R0
601
+
602
+ # La lista nunca se imprime al iniciar. Solicítela explícitamente.
603
+ orgm-bt project list --limit all
604
+ orgm-bt project list --limit 10
605
+ orgm-bt project list --search chinos --limit all
606
+
607
+ # Generar HTML, editar paneles con Tkinter y gestionar resultados.
608
+ orgm-bt calculate "Nave de los Chinos"
609
+ orgm-bt panels "Nave de los Chinos"
610
+ orgm-bt du "Nave de los Chinos" 1
611
+ orgm-bt finalize "Nave de los Chinos" 1
612
+ orgm-bt pdf "Nave de los Chinos" 1 --renderer chromium
613
+ ```
614
+
615
+ Sin subcomando, `orgm-bt` y `uv run local.py` muestran un menú corto: calcular,
616
+ ver proyectos (todos, cantidad o búsqueda), crear o editar paneles. No imprime una
617
+ tabla de proyectos antes de que el usuario la pida. Los switches legacy de
618
+ `local.py` siguen disponibles para instalaciones que aún usan `datos/local.json`.
619
+
620
+ ## Pendiente
621
+
622
+ - **Diagrama Unifilar**: Procesamiento básico implementado (archivo DU), pendiente visualización completa y generación automática del diagrama
623
+ - **Feed Lugs**: Alimentación a través de terminal (no va en un breaker). Pendiente implementar en cálculos y documentos.
624
+ - **FastAPI simple de uso interno**: Implementar API REST simple para uso interno del equipo, permitiendo:
625
+ - Crear y gestionar proyectos
626
+ - Ejecutar cálculos via API
627
+ - Obtener resultados y documentos generados
628
+ - Subir archivos de entrada
629
+ - **Actualizar Alembic con datos de local.json**: Crear migraciones de Alembic para almacenar en base de datos todos los campos de configuración que actualmente se guardan en `local.json`, excepto:
630
+ - `path`: Ruta local (no se almacena en BD)
631
+ - `output`: Ruta local de salida (no se almacena en BD)
632
+ - `fecha_creacion` y `fecha_calculo`: Se pueden usar timestamps de BD
633
+
634
+ Esto permitirá centralizar la gestión de proyectos y configuraciones en la base de datos en lugar de archivos JSON locales.