Browse Source

add how it works

Matthew Trejo 3 days ago
parent
commit
2904eb2cca
7 changed files with 188 additions and 59 deletions
  1. BIN
      __pycache__/routes.cpython-313.pyc
  2. 1 0
      app.py
  3. BIN
      instance/solarcalc.db
  4. 4 0
      routes.py
  5. 3 0
      templates/base.html
  6. 105 59
      templates/configuracion.html
  7. 75 0
      templates/methodology.html

BIN
__pycache__/routes.cpython-313.pyc


+ 1 - 0
app.py

@@ -5,6 +5,7 @@ def create_app():
     app = Flask(__name__)
     app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///solarcalc.db'
     app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+    app.config['SECRET_KEY'] = 'dev-secret-key-12345'
 
     db.init_app(app)
 

BIN
instance/solarcalc.db


+ 4 - 0
routes.py

@@ -8,6 +8,10 @@ main = Blueprint('main', __name__)
 def index():
     return render_template('index.html')
 
+@main.route('/metodologia')
+def metodologia():
+    return render_template('methodology.html')
+
 @main.route('/configuracion', methods=['GET', 'POST'])
 def configuracion():
     config_precio = Configuracion.query.filter_by(clave='precio_kwh').first()

+ 3 - 0
templates/base.html

@@ -25,6 +25,9 @@
             </button>
             <div class="collapse navbar-collapse" id="navbarNav">
                 <ul class="navbar-nav ms-auto">
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{ url_for('main.metodologia') }}">Cómo Funciona</a>
+                    </li>
                     <li class="nav-item">
                         <a class="nav-link" href="{{ url_for('main.casas') }}">Casas</a>
                     </li>

+ 105 - 59
templates/configuracion.html

@@ -2,8 +2,8 @@
 
 {% block content %}
 <div class="row justify-content-center">
-    <div class="col-md-6">
-        <div class="card">
+    <div class="col-md-8">
+        <div class="card mb-4">
             <div class="card-header bg-secondary text-white">Configuración del Sistema</div>
             <div class="card-body">
                 <form method="POST">
@@ -18,63 +18,17 @@
             </div>
         </div>
 
-        <div class="card mt-4">
-            <div class="card-header {{ 'bg-warning' if casa_editar else 'bg-success' }} text-white">
-                {{ 'Editar Casa' if casa_editar else 'Agregar Nueva Casa' }}
-            </div>
-            <div class="card-body">
-                <form action="{{ url_for('main.editar_casa', id_casa=casa_editar.id_casa) if casa_editar else url_for('main.nueva_casa') }}" method="POST">
-                    <div class="mb-3">
-                        <label for="nombre" class="form-label">Nombre de la Casa</label>
-                        <input type="text" name="nombre" class="form-control" placeholder="Ej: Casa de Playa" value="{{ casa_editar.nombre if casa_editar else '' }}" required>
-                    </div>
-                    <div class="row">
-                        <div class="col-md-6 mb-3">
-                            <label for="id_ciudad" class="form-label">Ciudad / Provincia</label>
-                            <select name="id_ciudad" class="form-select" required>
-                                {% for ciudad in ciudades %}
-                                <option value="{{ ciudad.id_ciudad }}" {{ 'selected' if casa_editar and casa_editar.id_ciudad == ciudad.id_ciudad else '' }}>
-                                    {{ ciudad.nombre_ciudad }} ({{ ciudad.provincia }})
-                                </option>
-                                {% endfor %}
-                            </select>
-                        </div>
-                        <div class="col-md-6 mb-3">
-                            <label for="area_techo" class="form-label">Área de Techo Disponible (m²)</label>
-                            <input type="number" step="0.1" name="area_techo" class="form-control" value="{{ casa_editar.area_techo if casa_editar else '' }}" required>
-                        </div>
-                    </div>
-                    <div class="row">
-                        <div class="col-md-6 mb-3">
-                            <label for="orientacion" class="form-label">Orientación del Techo</label>
-                            <select class="form-select" id="orientacion" name="orientacion" required>
-                                {% set orientaciones = ['Norte', 'Sur', 'Este', 'Oeste', 'Noreste', 'Noroeste', 'Sureste', 'Suroeste', 'Plano'] %}
-                                {% for o in orientaciones %}
-                                <option value="{{ o }}" {{ 'selected' if casa_editar and casa_editar.orientacion == o else '' }}>{{ o }}</option>
-                                {% endfor %}
-                            </select>
-                        </div>
-                        <div class="col-md-6 mb-3">
-                            <label for="inclinacion" class="form-label">Inclinación del Techo (Grados)</label>
-                            <input type="number" step="1" class="form-control" id="inclinacion" name="inclinacion" value="{{ casa_editar.inclinacion if casa_editar else '0' }}" required>
-                            <div class="form-text">0° es plano. Típico es 15-30°.</div>
-                        </div>
-                    </div>
-                    <button type="submit" class="btn {{ 'btn-warning' if casa_editar else 'btn-success' }}">
-                        {{ 'Actualizar Casa' if casa_editar else 'Guardar Casa' }}
-                    </button>
-                    {% if casa_editar %}
-                    <a href="{{ url_for('main.configuracion') }}" class="btn btn-secondary">Cancelar</a>
-                    {% endif %}
-                </form>
+        <div class="card">
+            <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
+                <span>Gestión de Casas</span>
+                <button type="button" class="btn btn-light btn-sm" data-bs-toggle="modal" data-bs-target="#casaModal" onclick="setupModal('new')">
+                    + Nueva Casa
+                </button>
             </div>
-        </div>
-
-        {% if casas %}
-        <div class="card mt-4 mb-4">
-            <div class="card-header bg-info text-white">Casas Registradas</div>
             <div class="card-body">
-                <div class="table-responsive">
+                <h5 class="card-title">Casas Registradas</h5>
+                {% if casas %}
+                <div class="table-responsive mb-4">
                     <table class="table table-hover">
                         <thead>
                             <tr>
@@ -94,7 +48,18 @@
                                 <td>{{ casa.orientacion }}</td>
                                 <td>
                                     <div class="btn-group" role="group">
-                                        <a href="{{ url_for('main.configuracion', edit_id=casa.id_casa) }}" class="btn btn-sm btn-warning">Editar</a>
+                                        <button type="button" class="btn btn-sm btn-warning" 
+                                            data-bs-toggle="modal" 
+                                            data-bs-target="#casaModal"
+                                            onclick="setupModal('edit', {
+                                                nombre: '{{ casa.nombre }}',
+                                                id_ciudad: '{{ casa.id_ciudad }}',
+                                                area_techo: '{{ casa.area_techo }}',
+                                                orientacion: '{{ casa.orientacion }}',
+                                                inclinacion: '{{ casa.inclinacion }}'
+                                            }, '{{ url_for('main.editar_casa', id_casa=casa.id_casa) }}')">
+                                            Editar
+                                        </button>
                                         <form action="{{ url_for('main.eliminar_casa', id_casa=casa.id_casa) }}" method="POST" onsubmit="return confirm('¿Estás seguro de eliminar esta casa?');" style="display: inline;">
                                             <button type="submit" class="btn btn-sm btn-danger">Eliminar</button>
                                         </form>
@@ -105,9 +70,90 @@
                         </tbody>
                     </table>
                 </div>
+                {% else %}
+                <div class="alert alert-info mb-4">No hay casas registradas.</div>
+                {% endif %}
             </div>
         </div>
-        {% endif %}
     </div>
 </div>
+
+<!-- Modal -->
+<div class="modal fade" id="casaModal" tabindex="-1" aria-labelledby="casaModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="casaModalLabel">Gestión de Casa</h5>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <form id="casaForm" method="POST" action="{{ url_for('main.nueva_casa') }}">
+                    <div class="mb-3">
+                        <label for="nombre" class="form-label">Nombre de la Casa</label>
+                        <input type="text" name="nombre" id="nombre" class="form-control" placeholder="Ej: Casa de Playa" required>
+                    </div>
+                    <div class="mb-3">
+                        <label for="id_ciudad" class="form-label">Ciudad / Provincia</label>
+                        <select name="id_ciudad" id="id_ciudad" class="form-select" required>
+                            {% for ciudad in ciudades %}
+                            <option value="{{ ciudad.id_ciudad }}">
+                                {{ ciudad.nombre_ciudad }} ({{ ciudad.provincia }})
+                            </option>
+                            {% endfor %}
+                        </select>
+                    </div>
+                    <div class="mb-3">
+                        <label for="area_techo" class="form-label">Área de Techo Disponible (m²)</label>
+                        <input type="number" step="0.1" name="area_techo" id="area_techo" class="form-control" required>
+                    </div>
+                    <div class="row">
+                        <div class="col-md-6 mb-3">
+                            <label for="orientacion" class="form-label">Orientación</label>
+                            <select class="form-select" id="orientacion" name="orientacion" required>
+                                {% set orientaciones = ['Norte', 'Sur', 'Este', 'Oeste', 'Noreste', 'Noroeste', 'Sureste', 'Suroeste', 'Plano'] %}
+                                {% for o in orientaciones %}
+                                <option value="{{ o }}">{{ o }}</option>
+                                {% endfor %}
+                            </select>
+                        </div>
+                        <div class="col-md-6 mb-3">
+                            <label for="inclinacion" class="form-label">Inclinación (°)</label>
+                            <input type="number" step="1" class="form-control" id="inclinacion" name="inclinacion" value="0" required>
+                            <div class="form-text">0° es plano. Típico es 15-30°.</div>
+                        </div>
+                    </div>
+                    <div class="d-grid">
+                        <button type="submit" class="btn btn-primary" id="modalSubmitBtn">Guardar Casa</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+function setupModal(mode, data, actionUrl) {
+    const form = document.getElementById('casaForm');
+    const title = document.getElementById('casaModalLabel');
+    const btn = document.getElementById('modalSubmitBtn');
+    
+    if (mode === 'new') {
+        title.textContent = 'Agregar Nueva Casa';
+        btn.textContent = 'Guardar Casa';
+        form.action = "{{ url_for('main.nueva_casa') }}";
+        form.reset();
+        document.getElementById('inclinacion').value = '0';
+    } else if (mode === 'edit') {
+        title.textContent = 'Editar Casa';
+        btn.textContent = 'Actualizar Casa';
+        form.action = actionUrl;
+        
+        document.getElementById('nombre').value = data.nombre;
+        document.getElementById('id_ciudad').value = data.id_ciudad;
+        document.getElementById('area_techo').value = data.area_techo;
+        document.getElementById('orientacion').value = data.orientacion;
+        document.getElementById('inclinacion').value = data.inclinacion;
+    }
+}
+</script>
 {% endblock %}

+ 75 - 0
templates/methodology.html

@@ -0,0 +1,75 @@
+{% extends "base.html" %}
+
+{% block content %}
+<div class="row justify-content-center">
+    <div class="col-md-10">
+        <div class="card shadow-sm mb-4">
+            <div class="card-header bg-info text-white">
+                <h2 class="h4 mb-0">Metodología de Cálculo</h2>
+            </div>
+            <div class="card-body">
+                <p class="lead">Esta aplicación utiliza modelos científicos estándar para estimar la generación de energía fotovoltaica y su viabilidad económica.</p>
+                
+                <hr>
+
+                <h3 class="h5 text-primary mt-4">1. El Modelo Científico (La Fórmula)</h3>
+                <p>Para el cálculo de la energía generada, utilizamos la fórmula estándar de estimación fotovoltaica global:</p>
+                
+                <div class="alert alert-secondary text-center fs-5">
+                    <strong>E = A · r · H · PR</strong>
+                </div>
+
+                <ul class="list-group list-group-flush mb-3">
+                    <li class="list-group-item">
+                        <strong>E (Energía):</strong> Es la energía generada (en kWh).
+                    </li>
+                    <li class="list-group-item">
+                        <strong>A (Área):</strong> El área total de los paneles solares (en m²). <br>
+                        <em>Cálculo: Área del Panel × Cantidad de Paneles.</em>
+                    </li>
+                    <li class="list-group-item">
+                        <strong>r (Rendimiento/Eficiencia):</strong> La eficiencia del panel solar (ej. 18% = 0.18).
+                    </li>
+                    <li class="list-group-item">
+                        <strong>H (Irradiación):</strong> La radiación solar media sobre los paneles (en kWh/m²). Este dato varía según la ciudad seleccionada.
+                    </li>
+                    <li class="list-group-item">
+                        <strong>PR (Performance Ratio):</strong> Coeficiente de pérdidas (por calor, cables, polvo, inversor). Usamos un valor estándar de <strong>0.75 (75%)</strong>.
+                    </li>
+                </ul>
+                
+                <p class="text-muted small">
+                    * Nota: Para el cálculo mensual, multiplicamos el resultado diario por 30 días.
+                    <br>
+                    * Se aplican factores de corrección adicionales según la orientación e inclinación del techo de la casa.
+                </p>
+
+                <h3 class="h5 text-primary mt-4">2. Análisis Económico (ROI)</h3>
+                <p>Calculamos el Retorno de Inversión (ROI) comparando el costo del sistema con el ahorro generado en la factura eléctrica.</p>
+                
+                <div class="card bg-light mb-3">
+                    <div class="card-body">
+                        <p class="mb-2"><strong>Tiempo de Recuperación (Años):</strong></p>
+                        <code>Costo Total de Paneles / (Ahorro Mensual × 12)</code>
+                    </div>
+                </div>
+
+                <h3 class="h5 text-primary mt-4">3. Impacto Ambiental</h3>
+                <p>Estimamos la huella de carbono reducida gracias a la generación de energía limpia.</p>
+                <ul>
+                    <li><strong>Factor de emisión:</strong> ≈ 0.4 kg CO₂ por kWh generado.</li>
+                    <li><strong>Equivalencia:</strong> Se muestra una estimación de árboles equivalentes plantados.</li>
+                </ul>
+
+                <h3 class="h5 text-primary mt-4">4. Flujo de Datos</h3>
+                <ol>
+                    <li>El usuario configura una <strong>Casa</strong> (ubicación, techo).</li>
+                    <li>Selecciona un modelo de <strong>Panel Solar</strong> del catálogo.</li>
+                    <li>El sistema obtiene la <strong>Irradiación (H)</strong> de la base de datos según la ciudad.</li>
+                    <li>Se procesan los cálculos y se presentan los resultados de generación, ahorro y amortización.</li>
+                </ol>
+            </div>
+        </div>
+    </div>
+</div>
+{% endblock %}