refactor: Atualiza app.py com imports dos modulos e fallback completo
Browse files
app.py
CHANGED
|
@@ -1,248 +1,538 @@
|
|
| 1 |
"""
|
| 2 |
-
Agente CBMGO - Interface Principal Gradio
|
| 3 |
Sistema Inteligente de Prevencao de Incendio - NT-01/2025
|
|
|
|
| 4 |
"""
|
|
|
|
| 5 |
import gradio as gr
|
| 6 |
import math
|
| 7 |
from datetime import datetime
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
}
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
def
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
ocup = ocupacao.lower()
|
| 30 |
-
if area_m2 > 750 or ocup in ["comercial", "servicos"]:
|
| 31 |
-
ex.append("hidrantes")
|
| 32 |
-
if altura_m > 12:
|
| 33 |
-
ex += ["iluminacao_emergencia", "saidas_emergencia"]
|
| 34 |
-
if area_m2 > 1000:
|
| 35 |
-
ex.append("spda")
|
| 36 |
-
if ocup == "industrial" and area_m2 > 2000:
|
| 37 |
-
ex += ["chuveiros_automaticos", "reservatorio_incendio"]
|
| 38 |
-
if lotacao > 100:
|
| 39 |
-
ex += ["alarme_incendio", "deteccao_automatica"]
|
| 40 |
-
return list(set(ex))
|
| 41 |
-
|
| 42 |
-
def aba_calculadora(nome, area_m2, altura_m, ocupacao, lotacao):
|
| 43 |
-
if area_m2 <= 0:
|
| 44 |
-
return "Erro: Informe a area total valida.", "", ""
|
| 45 |
-
grupos = {"residencial":"A","comercial":"D","servicos":"D",
|
| 46 |
-
"educacional":"G","saude":"H","industrial":"F",
|
| 47 |
-
"deposito":"J","reuniao":"C","esporte":"C"}
|
| 48 |
-
grupo = grupos.get(ocupacao.lower(), "D")
|
| 49 |
-
qtd, cap = calcular_extintores(area_m2, grupo)
|
| 50 |
-
sist, vazao = calcular_hidrantes(altura_m)
|
| 51 |
-
reserva = round(vazao * 60 / 1000, 1)
|
| 52 |
-
ex = aplicar_regras(area_m2, altura_m, ocupacao, lotacao)
|
| 53 |
-
data = datetime.now().strftime("%d/%m/%Y")
|
| 54 |
-
|
| 55 |
-
calc = (
|
| 56 |
-
"=== CALCULOS NT-01/2025 ===\n"
|
| 57 |
-
+ f"Edificacao: {nome}\n"
|
| 58 |
-
+ f"Ocupacao: {ocupacao} | Grupo: {grupo}\n"
|
| 59 |
-
+ f"Area: {area_m2:.1f} m2 | Altura: {altura_m:.1f} m | Lot: {int(lotacao)}\n\n"
|
| 60 |
-
+ f"EXTINTORES: {qtd} un. | Cap: {cap} | Dist.max: 15m\n"
|
| 61 |
-
+ f"HIDRANTES: {sist} | Vazao: {vazao} L/min | Reserva: {reserva} m3\n"
|
| 62 |
-
+ ("SPDA: OBRIGATORIO\n" if area_m2 > 1000 else "SPDA: Verificar\n")
|
| 63 |
-
+ ("ILUM.EMERG: OBRIGATORIA\n" if altura_m > 12 else "ILUM.EMERG: Verificar\n")
|
| 64 |
-
)
|
| 65 |
-
exig_txt = "\n".join([f" - {e.replace('_',' ').title()}" for e in ex])
|
| 66 |
-
exig = f"=== EXIGENCIAS ({len(ex)} sistemas) ===\n{exig_txt}\n\nRef: NT-01/2025 CBMGO"
|
| 67 |
-
exig_desc = ", ".join([e.replace("_"," ") for e in ex])
|
| 68 |
-
memorial = (
|
| 69 |
-
"MEMORIAL DESCRITIVO - PSCIP\n"
|
| 70 |
-
+ f"Data: {data} | Edificacao: {nome} | Ref: NT-01/2025 CBMGO\n\n"
|
| 71 |
-
+ "1. IDENTIFICACAO\n"
|
| 72 |
-
+ f" Uso: {ocupacao.title()} | Grupo NT-01: {grupo}\n"
|
| 73 |
-
+ f" Area: {area_m2:.2f} m2 | Altura: {altura_m:.2f} m\n\n"
|
| 74 |
-
+ f"2. SISTEMAS EXIGIDOS (Grupo {grupo})\n"
|
| 75 |
-
+ f" {exig_desc}\n\n"
|
| 76 |
-
+ "3. EXTINTORES PORTATEIS\n"
|
| 77 |
-
+ f" Qtd: {qtd} un. | Cap: {cap} | Dist.max: 15m\n"
|
| 78 |
-
+ " Distribuicao conforme Anexo B NT-01/2025\n\n"
|
| 79 |
-
+ "4. SISTEMA DE HIDRANTES\n"
|
| 80 |
-
+ f" Sistema: {sist} | Vazao: {vazao} L/min | Reserva: {reserva} m3\n"
|
| 81 |
-
+ " Conforme ABNT NBR 13714 e NT especifica CBMGO.\n\n"
|
| 82 |
-
+ "5. SINALIZACAO DE EMERGENCIA\n"
|
| 83 |
-
+ " Conforme ABNT NBR 13434.\n\n"
|
| 84 |
-
+ "6. ILUMINACAO DE EMERGENCIA\n"
|
| 85 |
-
+ (" Obrigatoria. ABNT NBR 10898.\n\n" if altura_m > 12 else " Verificar necessidade.\n\n")
|
| 86 |
-
+ "7. SPDA\n"
|
| 87 |
-
+ (" Obrigatorio. ABNT NBR 5419.\n\n" if area_m2 > 1000 else " Verificar necessidade.\n\n")
|
| 88 |
-
+ "Responsavel Tecnico: _______________ CREA/CAU: ___________\n"
|
| 89 |
-
)
|
| 90 |
-
return calc, exig, memorial
|
| 91 |
-
|
| 92 |
-
def aba_auditoria(memorial_txt, area_m2, altura_m, ocupacao, lotacao):
|
| 93 |
-
if not memorial_txt or len(memorial_txt) < 30:
|
| 94 |
-
return "Insira o texto do memorial para auditar."
|
| 95 |
-
ex = aplicar_regras(area_m2, altura_m, ocupacao, lotacao)
|
| 96 |
-
termos = {
|
| 97 |
-
"extintores_portateis": ["extintor"],
|
| 98 |
-
"hidrantes": ["hidrante","mangotinho"],
|
| 99 |
-
"sinalizacao_emergencia": ["sinalizacao","sinaliza"],
|
| 100 |
-
"iluminacao_emergencia": ["iluminacao de emergencia"],
|
| 101 |
-
"spda": ["spda","para-raios"],
|
| 102 |
-
"alarme_incendio": ["alarme","deteccao"],
|
| 103 |
-
"chuveiros_automaticos": ["chuveiro","sprinkler"],
|
| 104 |
-
"saidas_emergencia": ["saida de emergencia","rota de fuga"],
|
| 105 |
}
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
# INTERFACE GRADIO
|
| 154 |
-
# ============================================================
|
| 155 |
-
with gr.Blocks(title="Agente CBMGO - NT-01/2025", theme=gr.themes.Base()) as demo:
|
| 156 |
-
gr.Markdown(
|
| 157 |
-
"# Agente CBMGO\n"
|
| 158 |
-
"### Sistema Inteligente de Prevencao de Incendio - NT-01/2025\n"
|
| 159 |
-
"> Apoio a Responsaveis Tecnicos (RT) - CBMGO Goias"
|
| 160 |
-
)
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
with gr.Tabs():
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
| 164 |
with gr.Row():
|
| 165 |
with gr.Column():
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
"saude","servicos","reuniao","esporte","deposito"],
|
| 173 |
-
value="comercial"
|
| 174 |
)
|
| 175 |
-
|
| 176 |
-
btn1 = gr.Button("Calcular Exigencias", variant="primary")
|
| 177 |
with gr.Column():
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
with gr.Row():
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
with gr.Row():
|
| 187 |
with gr.Column():
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
)
|
| 198 |
-
|
| 199 |
-
btn2 = gr.Button("Auditar Memorial", variant="primary")
|
| 200 |
with gr.Column():
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
with gr.Row():
|
| 208 |
with gr.Column():
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
gr.
|
| 214 |
-
|
| 215 |
-
s_pran = gr.Checkbox(label="Pranchas/Plantas (DWG/PDF)")
|
| 216 |
-
s_form = gr.Checkbox(label="Formulario RT")
|
| 217 |
-
btn3 = gr.Button("Verificar Pacote", variant="primary")
|
| 218 |
with gr.Column():
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
with gr.
|
| 224 |
gr.Markdown("""
|
| 225 |
-
## Agente CBMGO
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
- **
|
| 231 |
-
- **
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
|
|
|
| 246 |
|
| 247 |
if __name__ == "__main__":
|
| 248 |
demo.launch()
|
|
|
|
| 1 |
"""
|
| 2 |
+
app.py - Agente CBMGO - Interface Principal Gradio
|
| 3 |
Sistema Inteligente de Prevencao de Incendio - NT-01/2025
|
| 4 |
+
CERCON - Corpo de Bombeiros Militar de Goias
|
| 5 |
"""
|
| 6 |
+
|
| 7 |
import gradio as gr
|
| 8 |
import math
|
| 9 |
from datetime import datetime
|
| 10 |
|
| 11 |
+
# Importar modulos com fallback gracioso
|
| 12 |
+
try:
|
| 13 |
+
from modules.classificador import ClassificadorOcupacao
|
| 14 |
+
_classificador = ClassificadorOcupacao()
|
| 15 |
+
USE_CLASSIFICADOR = True
|
| 16 |
+
except Exception as e:
|
| 17 |
+
print(f"[WARN] Modulo classificador nao disponivel: {e}")
|
| 18 |
+
USE_CLASSIFICADOR = False
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
from modules.calculadora import CalculadoraIncendio
|
| 22 |
+
_calculadora = CalculadoraIncendio()
|
| 23 |
+
USE_CALCULADORA = True
|
| 24 |
+
except Exception as e:
|
| 25 |
+
print(f"[WARN] Modulo calculadora nao disponivel: {e}")
|
| 26 |
+
USE_CALCULADORA = False
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
from modules.rag_normas import RAGNormas
|
| 30 |
+
_rag = RAGNormas()
|
| 31 |
+
USE_RAG = True
|
| 32 |
+
except Exception as e:
|
| 33 |
+
print(f"[WARN] Modulo RAG nao disponivel: {e}")
|
| 34 |
+
USE_RAG = False
|
| 35 |
+
|
| 36 |
+
try:
|
| 37 |
+
from modules.auditor import AuditorProjetos
|
| 38 |
+
_auditor = AuditorProjetos()
|
| 39 |
+
USE_AUDITOR = True
|
| 40 |
+
except Exception as e:
|
| 41 |
+
print(f"[WARN] Modulo auditor nao disponivel: {e}")
|
| 42 |
+
USE_AUDITOR = False
|
| 43 |
+
|
| 44 |
+
try:
|
| 45 |
+
from modules.memorial_generator import MemorialGenerator
|
| 46 |
+
_memorial = MemorialGenerator()
|
| 47 |
+
USE_MEMORIAL = True
|
| 48 |
+
except Exception as e:
|
| 49 |
+
print(f"[WARN] Modulo memorial nao disponivel: {e}")
|
| 50 |
+
USE_MEMORIAL = False
|
| 51 |
+
|
| 52 |
+
try:
|
| 53 |
+
from modules.submissao import SubmissaoSIAPI
|
| 54 |
+
_submissao = SubmissaoSIAPI()
|
| 55 |
+
USE_SUBMISSAO = True
|
| 56 |
+
except Exception as e:
|
| 57 |
+
print(f"[WARN] Modulo submissao nao disponivel: {e}")
|
| 58 |
+
USE_SUBMISSAO = False
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
# =============================================================================
|
| 62 |
+
# FALLBACKS LOCAIS (quando modulos nao estao disponiveis)
|
| 63 |
+
# =============================================================================
|
| 64 |
+
|
| 65 |
+
GRUPOS_OCUPACAO = {
|
| 66 |
+
"A-1": "Residencial unifamiliar (casa, sobrado)",
|
| 67 |
+
"A-2": "Residencial multifamiliar (apartamento, flat)",
|
| 68 |
+
"B-1": "Hospedagem transitoria (hotel, motel, pousada)",
|
| 69 |
+
"B-2": "Hospedagem longa permanencia (apart-hotel)",
|
| 70 |
+
"C-1": "Comercio pequeno porte (loja, farmacia, padaria)",
|
| 71 |
+
"C-2": "Comercio medio/grande porte (supermercado, shopping)",
|
| 72 |
+
"D-1": "Reuniao publica - esporte/lazer (ginasio, estadio)",
|
| 73 |
+
"D-2": "Reuniao publica - cultura/religiao (teatro, igreja)",
|
| 74 |
+
"D-3": "Reuniao publica - ensino (escola, universidade)",
|
| 75 |
+
"E-1": "Saude e assistencia (hospital, clinica, UBS)",
|
| 76 |
+
"F-1": "Servico profissional (escritorio, banco, consultorio)",
|
| 77 |
+
"F-2": "Servico de transporte (aeroporto, rodoviaria)",
|
| 78 |
+
"G-1": "Servicos automotivos (garagem, posto, oficina)",
|
| 79 |
+
"H-1": "Industrial baixo risco (alimenticio, textil)",
|
| 80 |
+
"H-2": "Industrial medio risco (metalurgica, moveleira)",
|
| 81 |
+
"H-3": "Industrial alto risco (quimica, petroquimica)",
|
| 82 |
+
"I-1": "Deposito baixo risco (arquivo, papel)",
|
| 83 |
+
"I-2": "Deposito medio risco (madeira, borracha)",
|
| 84 |
+
"I-3": "Deposito alto risco (inflamaveis, quimicos)",
|
| 85 |
+
"J-1": "Explosivos e inflamaveis especiais (refinaria)",
|
| 86 |
+
}
|
| 87 |
|
| 88 |
+
|
| 89 |
+
def calcular_extintores_fallback(area_m2, grupo):
|
| 90 |
+
letra = grupo.split("-")[0] if "-" in grupo else grupo[0]
|
| 91 |
+
risco = "alto" if letra in ["H","I","J"] else ("medio" if letra in ["C","D","G"] else "baixo")
|
| 92 |
+
area_por_ext = 150 if risco == "alto" else (250 if risco == "medio" else 500)
|
| 93 |
+
quantidade = max(2, math.ceil(area_m2 / area_por_ext))
|
| 94 |
+
return {
|
| 95 |
+
"risco": risco, "area_por_extintor": area_por_ext,
|
| 96 |
+
"quantidade": quantidade, "tipo": "ABC 6kg"
|
| 97 |
}
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def verificar_sistemas_fallback(area_m2, pavimentos, grupo):
|
| 101 |
+
altura = pavimentos * 3.0
|
| 102 |
+
letra = grupo.split("-")[0] if "-" in grupo else grupo[0]
|
| 103 |
+
return {
|
| 104 |
+
"hidrante": area_m2 > 750 or pavimentos >= 3,
|
| 105 |
+
"spda": altura > 15 or area_m2 > 1000,
|
| 106 |
+
"iluminacao_emergencia": area_m2 > 200 or pavimentos >= 2,
|
| 107 |
+
"sprinkler": altura > 30 or (letra in ["H","I"] and area_m2 > 2500),
|
| 108 |
+
"brigada": area_m2 > 750,
|
| 109 |
+
"alarme": letra in ["E","B"] or area_m2 > 1500,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
}
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
# =============================================================================
|
| 114 |
+
# FUNCOES DA INTERFACE
|
| 115 |
+
# =============================================================================
|
| 116 |
+
|
| 117 |
+
def calcular_medidas(area_m2, pavimentos, grupo_codigo):
|
| 118 |
+
"""Calcula todas as medidas de seguranca para a edificacao"""
|
| 119 |
+
try:
|
| 120 |
+
if USE_CALCULADORA:
|
| 121 |
+
return _calculadora.calcular_completo(area_m2, pavimentos, grupo_codigo)
|
| 122 |
+
except Exception as e:
|
| 123 |
+
print(f"Erro no modulo calculadora: {e}")
|
| 124 |
+
|
| 125 |
+
# Fallback local
|
| 126 |
+
ext = calcular_extintores_fallback(area_m2, grupo_codigo)
|
| 127 |
+
sis = verificar_sistemas_fallback(area_m2, pavimentos, grupo_codigo)
|
| 128 |
+
altura = pavimentos * 3.0
|
| 129 |
+
|
| 130 |
+
resultado = f"""CALCULOS DE SEGURANCA CONTRA INCENDIO - NT-01/2025 CBMGO
|
| 131 |
+
{"="*60}
|
| 132 |
+
|
| 133 |
+
EDIFICACAO:
|
| 134 |
+
Grupo de Ocupacao: {grupo_codigo}
|
| 135 |
+
Area Total: {area_m2:.1f} m2
|
| 136 |
+
Pavimentos: {pavimentos}
|
| 137 |
+
Altura Estimada: {altura:.1f} m
|
| 138 |
+
Risco: {ext["risco"].upper()}
|
| 139 |
+
|
| 140 |
+
EXTINTORES DE INCENDIO:
|
| 141 |
+
Quantidade minima: {ext["quantidade"]} extintores
|
| 142 |
+
Tipo: {ext["tipo"]} (Classe ABC)
|
| 143 |
+
Area por extintor: {ext["area_por_extintor"]} m2
|
| 144 |
+
Base: ABNT NBR 12693
|
| 145 |
+
|
| 146 |
+
SISTEMAS OBRIGATORIOS:
|
| 147 |
+
Hidrantes/Mangotinhos: {"OBRIGATORIO" if sis["hidrante"] else "Nao obrigatorio"}
|
| 148 |
+
SPDA (Para-raios): {"OBRIGATORIO" if sis["spda"] else "Verificar necessidade"}
|
| 149 |
+
Iluminacao Emergencia: {"OBRIGATORIA" if sis["iluminacao_emergencia"] else "Recomendada"}
|
| 150 |
+
Sprinklers: {"OBRIGATORIO" if sis["sprinkler"] else "Nao obrigatorio para esta area"}
|
| 151 |
+
Brigada de Incendio: {"OBRIGATORIA" if sis["brigada"] else "Recomendada"}
|
| 152 |
+
Sistema de Alarme: {"OBRIGATORIO" if sis["alarme"] else "Verificar necessidade"}
|
| 153 |
+
|
| 154 |
+
SAIDAS DE EMERGENCIA (ABNT NBR 9077):
|
| 155 |
+
Largura minima: 1,20 m
|
| 156 |
+
Distancia maxima: 30 m (baixo risco) / 20 m (alto risco)
|
| 157 |
+
|
| 158 |
+
{"="*60}
|
| 159 |
+
Nota: Estes calculos sao estimativas. O PPCI completo deve ser
|
| 160 |
+
elaborado por profissional habilitado com ART/RRT registrada.
|
| 161 |
+
Data: {datetime.now().strftime("%d/%m/%Y %H:%M")}"""
|
| 162 |
+
|
| 163 |
+
return resultado
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def consultar_normas(pergunta):
|
| 167 |
+
"""Consulta o RAG de normas NT-01/2025"""
|
| 168 |
+
if not pergunta.strip():
|
| 169 |
+
return "Por favor, digite uma pergunta sobre as normas de prevencao de incendio."
|
| 170 |
+
|
| 171 |
+
try:
|
| 172 |
+
if USE_RAG:
|
| 173 |
+
return _rag.consultar(pergunta)
|
| 174 |
+
except Exception as e:
|
| 175 |
+
print(f"Erro no modulo RAG: {e}")
|
| 176 |
+
|
| 177 |
+
# Fallback: respostas baseadas em palavras-chave
|
| 178 |
+
pergunta_lower = pergunta.lower()
|
| 179 |
+
|
| 180 |
+
if any(w in pergunta_lower for w in ["extintor", "extintores"]):
|
| 181 |
+
return """EXTINTORES DE INCENDIO - NT-01/2025 CBMGO
|
| 182 |
+
|
| 183 |
+
Conforme NT-01/2025 e ABNT NBR 12693:
|
| 184 |
+
- BAIXO RISCO (A, B, F): 1 extintor a cada 500 m2
|
| 185 |
+
- MEDIO RISCO (C, D, G): 1 extintor a cada 250 m2
|
| 186 |
+
- ALTO RISCO (H, I, J): 1 extintor a cada 150 m2
|
| 187 |
+
- Minimo: 2 extintores por pavimento
|
| 188 |
+
- Tipo: ABC (po quimico) para uso geral
|
| 189 |
+
- Manutencao: Anual obrigatoria
|
| 190 |
+
- Sinalizar conforme ABNT NBR 13434"""
|
| 191 |
+
|
| 192 |
+
elif any(w in pergunta_lower for w in ["hidrante", "hidrantes"]):
|
| 193 |
+
return """SISTEMA DE HIDRANTES - NT-01/2025 CBMGO
|
| 194 |
+
|
| 195 |
+
Obrigatorio quando:
|
| 196 |
+
- Area total > 750 m2, OU
|
| 197 |
+
- Altura > 12 metros (aprox. 4 pavimentos)
|
| 198 |
+
|
| 199 |
+
Especificacoes (ABNT NBR 13714):
|
| 200 |
+
- Pressao minima: 10 m.c.a. no ponto mais desfavoravel
|
| 201 |
+
- Vazao minima: 300 L/min por hidrante
|
| 202 |
+
- Mangueira: DN 65mm para hidrante externo
|
| 203 |
+
- Distancia maxima entre hidrantes: 30 metros"""
|
| 204 |
+
|
| 205 |
+
elif any(w in pergunta_lower for w in ["spda", "para-raios", "pararaios"]):
|
| 206 |
+
return """SPDA - SISTEMA DE PROTECAO CONTRA DESCARGAS ATMOSFERICAS
|
| 207 |
+
|
| 208 |
+
Obrigatorio conforme ABNT NBR 5419 quando:
|
| 209 |
+
- Altura > 15 metros
|
| 210 |
+
- Area construida > 1.000 m2
|
| 211 |
+
- Edificacoes em areas de alta densidade de raios
|
| 212 |
+
|
| 213 |
+
O SPDA deve ser projetado por engenheiro eletricista habilitado."""
|
| 214 |
+
|
| 215 |
+
elif any(w in pergunta_lower for w in ["memorial", "ppci"]):
|
| 216 |
+
return """MEMORIAL DESCRITIVO (PPCI) - NT-01/2025 CBMGO
|
| 217 |
+
|
| 218 |
+
O PPCI deve conter:
|
| 219 |
+
1. Identificacao da edificacao e responsavel tecnico
|
| 220 |
+
2. Classificacao de ocupacao (Tabela 1 - NT-01/2025)
|
| 221 |
+
3. Medidas de seguranca adotadas
|
| 222 |
+
4. Memorial de calculos
|
| 223 |
+
5. Plantas tecnicas (planta baixa, cortes, fachadas)
|
| 224 |
+
6. ART/RRT do responsavel tecnico
|
| 225 |
+
|
| 226 |
+
Elaborado por: Engenheiro (CREA) ou Arquiteto (CAU) habilitado.
|
| 227 |
+
Aprovacao: CBMGO antes do inicio das obras."""
|
| 228 |
+
|
| 229 |
+
else:
|
| 230 |
+
return f"""CONSULTA NT-01/2025 CBMGO
|
| 231 |
+
|
| 232 |
+
Sua pergunta: "{pergunta}"
|
| 233 |
+
|
| 234 |
+
Nao encontrei uma resposta especifica para esta consulta.
|
| 235 |
+
|
| 236 |
+
Para perguntas sobre a NT-01/2025, voce pode pesquisar sobre:
|
| 237 |
+
- Classificacao de ocupacao (grupos A a J)
|
| 238 |
+
- Extintores de incendio (NBR 12693)
|
| 239 |
+
- Sistema de hidrantes (NBR 13714)
|
| 240 |
+
- Saidas de emergencia (NBR 9077)
|
| 241 |
+
- Iluminacao de emergencia (NBR 10898)
|
| 242 |
+
- PPCI e memorial descritivo
|
| 243 |
+
|
| 244 |
+
Para consultas especificas, entre em contato com o CBMGO:
|
| 245 |
+
Site: www.bombeiros.go.gov.br"""
|
| 246 |
+
|
| 247 |
+
|
| 248 |
+
def auditar_projeto(descricao_projeto):
|
| 249 |
+
"""Audita um projeto contra as normas NT-01/2025"""
|
| 250 |
+
if not descricao_projeto.strip():
|
| 251 |
+
return "Por favor, descreva o projeto para auditoria."
|
| 252 |
+
|
| 253 |
+
try:
|
| 254 |
+
if USE_AUDITOR:
|
| 255 |
+
return _auditor.auditar(descricao_projeto)
|
| 256 |
+
except Exception as e:
|
| 257 |
+
print(f"Erro no modulo auditor: {e}")
|
| 258 |
+
|
| 259 |
+
# Fallback local
|
| 260 |
+
verificacoes = []
|
| 261 |
+
desc_lower = descricao_projeto.lower()
|
| 262 |
+
|
| 263 |
+
checks = [
|
| 264 |
+
("extintor", "Extintores de incendio", "Verificar quantidade e distribuicao conforme NBR 12693"),
|
| 265 |
+
("saida", "Saidas de emergencia", "Verificar largura minima 1,20m e sinalizar conforme NBR 9077"),
|
| 266 |
+
("iluminacao", "Iluminacao de emergencia", "Autonomia minima 1h, 30 lux nas rotas de saida"),
|
| 267 |
+
("sinaliza", "Sinalizacao de seguranca", "Placas conforme ABNT NBR 13434"),
|
| 268 |
+
("hidrante", "Sistema de hidrantes", "Verificar obrigatoriedade pela area/altura"),
|
| 269 |
+
("spda", "SPDA para-raios", "Verificar necessidade pela altura/area"),
|
| 270 |
+
]
|
| 271 |
+
|
| 272 |
+
for keyword, item, obs in checks:
|
| 273 |
+
if keyword in desc_lower:
|
| 274 |
+
verificacoes.append(f"[OK] {item}: Mencionado no projeto")
|
| 275 |
+
else:
|
| 276 |
+
verificacoes.append(f"[ATENCAO] {item}: Nao mencionado - {obs}")
|
| 277 |
+
|
| 278 |
+
itens_str = chr(10).join(verificacoes)
|
| 279 |
+
return f"""AUDITORIA DO PROJETO - NT-01/2025 CBMGO
|
| 280 |
+
{"="*60}
|
| 281 |
+
|
| 282 |
+
PROJETO ANALISADO:
|
| 283 |
+
{descricao_projeto[:300]}{"..." if len(descricao_projeto) > 300 else ""}
|
| 284 |
+
|
| 285 |
+
VERIFICACOES:
|
| 286 |
+
{itens_str}
|
| 287 |
+
|
| 288 |
+
RECOMENDACOES:
|
| 289 |
+
- Verifique todos os itens marcados como [ATENCAO]
|
| 290 |
+
- Consulte a NT-01/2025 CBMGO para requisitos especificos
|
| 291 |
+
- O PPCI completo deve ser aprovado pelo CBMGO
|
| 292 |
+
|
| 293 |
+
Data: {datetime.now().strftime("%d/%m/%Y %H:%M")}"""
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
def gerar_memorial_func(tipo_edificacao, area, pavimentos, cidade, responsavel):
|
| 297 |
+
"""Gera memorial descritivo de PPCI"""
|
| 298 |
+
if not tipo_edificacao.strip():
|
| 299 |
+
return "Por favor, informe o tipo de edificacao."
|
| 300 |
+
|
| 301 |
+
try:
|
| 302 |
+
if USE_MEMORIAL:
|
| 303 |
+
return _memorial.gerar(tipo_edificacao, float(area), int(pavimentos), cidade, responsavel)
|
| 304 |
+
except Exception as e:
|
| 305 |
+
print(f"Erro no modulo memorial: {e}")
|
| 306 |
+
|
| 307 |
+
# Fallback local
|
| 308 |
+
grupo = "F-1"
|
| 309 |
+
for cod, desc in GRUPOS_OCUPACAO.items():
|
| 310 |
+
if any(w in tipo_edificacao.lower() for w in desc.lower().split()):
|
| 311 |
+
grupo = cod
|
| 312 |
+
break
|
| 313 |
+
|
| 314 |
+
area_f = float(area) if area else 200.0
|
| 315 |
+
pav_i = int(pavimentos) if pavimentos else 1
|
| 316 |
+
altura = pav_i * 3.0
|
| 317 |
+
ext = calcular_extintores_fallback(area_f, grupo)
|
| 318 |
+
sis = verificar_sistemas_fallback(area_f, pav_i, grupo)
|
| 319 |
+
|
| 320 |
+
return f"""MEMORIAL DESCRITIVO DE PREVENCAO E PROTECAO CONTRA INCENDIO E PANICO
|
| 321 |
+
PLANO DE PREVENCAO CONTRA INCENDIO - PPCI
|
| 322 |
+
{"="*70}
|
| 323 |
+
|
| 324 |
+
1. IDENTIFICACAO DO PROJETO
|
| 325 |
+
Edificacao: {tipo_edificacao}
|
| 326 |
+
Endereco: [Endereco completo], {cidade} - GO
|
| 327 |
+
Ocupacao: Grupo {grupo} - {GRUPOS_OCUPACAO.get(grupo, "Verificar classificacao")}
|
| 328 |
+
Area Total: {area_f:.2f} m2 | Pavimentos: {pav_i} | Altura: {altura:.2f} m
|
| 329 |
+
Data: {datetime.now().strftime("%d/%m/%Y")}
|
| 330 |
+
Responsavel Tecnico: {responsavel}
|
| 331 |
+
ART/RRT No: [A PREENCHER]
|
| 332 |
+
|
| 333 |
+
2. BASE LEGAL
|
| 334 |
+
- NT-01/2025 CBMGO (Norma Tecnica 01/2025)
|
| 335 |
+
- ABNT NBR 9077:2001 (Saidas de emergencia)
|
| 336 |
+
- Lei Estadual n. 15.802/2006
|
| 337 |
+
|
| 338 |
+
3. CLASSIFICACAO
|
| 339 |
+
- Grupo: {grupo} | Risco: {ext["risco"].upper()}
|
| 340 |
+
|
| 341 |
+
4. MEDIDAS DE SEGURANCA
|
| 342 |
+
4.1 Extintores: {ext["quantidade"]} extintores {ext["tipo"]}
|
| 343 |
+
(1 a cada {ext["area_por_extintor"]}m2, conforme NBR 12693)
|
| 344 |
+
4.2 Hidrantes: {"Sistema de hidrantes obrigatorio (NBR 13714)" if sis["hidrante"] else "Verificar necessidade com CBMGO"}
|
| 345 |
+
4.3 SPDA: {"Obrigatorio (ABNT NBR 5419)" if sis["spda"] else "Verificar necessidade"}
|
| 346 |
+
4.4 Iluminacao Emergencia: {"Obrigatoria - 1h autonomia (NBR 10898)" if sis["iluminacao_emergencia"] else "Recomendada"}
|
| 347 |
+
4.5 Sinalizacao: Conforme ABNT NBR 13434
|
| 348 |
+
4.6 Saidas de Emergencia: Largura minima 1,20m (ABNT NBR 9077)
|
| 349 |
+
|
| 350 |
+
5. RESPONSABILIDADE TECNICA
|
| 351 |
+
{cidade}, {datetime.now().strftime("%d/%m/%Y")}
|
| 352 |
+
{responsavel}
|
| 353 |
+
ART/RRT No: [A PREENCHER]
|
| 354 |
+
{"="*70}
|
| 355 |
+
FIM DO MEMORIAL DESCRITIVO"""
|
| 356 |
+
|
| 357 |
+
|
| 358 |
+
def preparar_siapi(tipo_edificacao, area, responsavel, cpf_responsavel, crea_cau):
|
| 359 |
+
"""Prepara documentos para submissao no SIAPI"""
|
| 360 |
+
try:
|
| 361 |
+
if USE_SUBMISSAO:
|
| 362 |
+
return _submissao.preparar_documentos(tipo_edificacao, float(area), responsavel, cpf_responsavel, crea_cau)
|
| 363 |
+
except Exception as e:
|
| 364 |
+
print(f"Erro no modulo submissao: {e}")
|
| 365 |
+
|
| 366 |
+
# Fallback
|
| 367 |
+
protocolo = f"CBMGO-{datetime.now().strftime('%Y%m%d')}-{hash(tipo_edificacao) % 10000:04d}"
|
| 368 |
+
|
| 369 |
+
return f"""PREPARACAO PARA SUBMISSAO SIAPI - CBMGO
|
| 370 |
+
{"="*60}
|
| 371 |
+
|
| 372 |
+
PROTOCOLO PROVISORIO: {protocolo}
|
| 373 |
+
Data: {datetime.now().strftime("%d/%m/%Y %H:%M")}
|
| 374 |
+
|
| 375 |
+
DADOS DA EDIFICACAO:
|
| 376 |
+
- Tipo: {tipo_edificacao}
|
| 377 |
+
- Area: {area} m2
|
| 378 |
+
- Responsavel Tecnico: {responsavel}
|
| 379 |
+
- Registro Profissional: {crea_cau}
|
| 380 |
+
|
| 381 |
+
DOCUMENTOS NECESSARIOS:
|
| 382 |
+
[x] PPCI completo (memorial + plantas)
|
| 383 |
+
[x] ART/RRT do responsavel tecnico
|
| 384 |
+
[x] Requerimento padrao CBMGO
|
| 385 |
+
[x] DARM quitado (taxa de vistoria)
|
| 386 |
+
[ ] Laudo de aprovacao do corpo tecnico
|
| 387 |
+
|
| 388 |
+
CHECKLIST DE PLANTAS:
|
| 389 |
+
[ ] Planta baixa cotada (escala 1:100 ou 1:50)
|
| 390 |
+
[ ] Planta de situacao e localizacao
|
| 391 |
+
[ ] Cortes transversal e longitudinal
|
| 392 |
+
[ ] Memorial descritivo assinado
|
| 393 |
+
[ ] Especificacoes tecnicas dos sistemas
|
| 394 |
+
|
| 395 |
+
COMO SUBMETER NO SIAPI:
|
| 396 |
+
1. Acesse: https://siapi.goias.gov.br
|
| 397 |
+
2. Faca login com CPF/CNPJ
|
| 398 |
+
3. Selecione "Novo Protocolo de Analise"
|
| 399 |
+
4. Preencha os dados da edificacao
|
| 400 |
+
5. Anexe os documentos em PDF (max 10MB cada)
|
| 401 |
+
6. Confirme e salve o protocolo
|
| 402 |
+
7. Aguarde analise do CBMGO (prazo: 30 dias)
|
| 403 |
+
|
| 404 |
+
Para duvidas: (62) 3201-5959 | cbmgo@bombeiros.go.gov.br
|
| 405 |
+
{"="*60}"""
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
# =============================================================================
|
| 409 |
# INTERFACE GRADIO
|
| 410 |
+
# =============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
|
| 412 |
+
with gr.Blocks(
|
| 413 |
+
title="CERCON - Agente CBMGO",
|
| 414 |
+
theme=gr.themes.Soft(primary_hue="red"),
|
| 415 |
+
) as demo:
|
| 416 |
+
|
| 417 |
+
gr.Markdown("""
|
| 418 |
+
# CERCON - Agente CBMGO
|
| 419 |
+
### Sistema Inteligente de Prevencao e Protecao contra Incendio e Panico
|
| 420 |
+
**Base normativa: NT-01/2025 | CBMGO - Corpo de Bombeiros Militar de Goias**
|
| 421 |
+
""")
|
| 422 |
+
|
| 423 |
with gr.Tabs():
|
| 424 |
+
|
| 425 |
+
# Tab 1: Calculadora
|
| 426 |
+
with gr.Tab("Calculadora de Seguranca"):
|
| 427 |
+
gr.Markdown("### Calcule as medidas de seguranca obrigatorias para sua edificacao")
|
| 428 |
with gr.Row():
|
| 429 |
with gr.Column():
|
| 430 |
+
area_input = gr.Number(label="Area Total (m2)", value=200.0, minimum=1)
|
| 431 |
+
pav_input = gr.Number(label="Numero de Pavimentos", value=1, minimum=1, step=1)
|
| 432 |
+
grupo_input = gr.Dropdown(
|
| 433 |
+
choices=list(GRUPOS_OCUPACAO.keys()),
|
| 434 |
+
value="F-1",
|
| 435 |
+
label="Grupo de Ocupacao (NT-01/2025)"
|
|
|
|
|
|
|
| 436 |
)
|
| 437 |
+
calc_btn = gr.Button("Calcular Medidas de Seguranca", variant="primary")
|
|
|
|
| 438 |
with gr.Column():
|
| 439 |
+
calc_output = gr.Textbox(label="Resultado", lines=25, show_copy_button=True)
|
| 440 |
+
calc_btn.click(calcular_medidas, inputs=[area_input, pav_input, grupo_input], outputs=calc_output)
|
| 441 |
+
|
| 442 |
+
# Tab 2: Consulta Normas
|
| 443 |
+
with gr.Tab("Consulta NT-01/2025"):
|
| 444 |
+
gr.Markdown("### Tire duvidas sobre a NT-01/2025 e normas de prevencao de incendio")
|
| 445 |
with gr.Row():
|
| 446 |
+
with gr.Column():
|
| 447 |
+
norma_input = gr.Textbox(
|
| 448 |
+
label="Sua pergunta",
|
| 449 |
+
placeholder="Ex: Quantos extintores preciso para um escritorio de 300m2?",
|
| 450 |
+
lines=3
|
| 451 |
+
)
|
| 452 |
+
norma_btn = gr.Button("Consultar", variant="primary")
|
| 453 |
+
gr.Examples(
|
| 454 |
+
examples=[
|
| 455 |
+
["Quantos extintores preciso para um escritorio de 500m2?"],
|
| 456 |
+
["Quando e obrigatorio instalar hidrantes?"],
|
| 457 |
+
["O que e SPDA e quando e obrigatorio?"],
|
| 458 |
+
["Como elaborar um PPCI para um hotel?"],
|
| 459 |
+
],
|
| 460 |
+
inputs=norma_input
|
| 461 |
+
)
|
| 462 |
+
with gr.Column():
|
| 463 |
+
norma_output = gr.Textbox(label="Resposta", lines=20, show_copy_button=True)
|
| 464 |
+
norma_btn.click(consultar_normas, inputs=norma_input, outputs=norma_output)
|
| 465 |
+
|
| 466 |
+
# Tab 3: Memorial PPCI
|
| 467 |
+
with gr.Tab("Gerar Memorial PPCI"):
|
| 468 |
+
gr.Markdown("### Gere um memorial descritivo de PPCI automaticamente")
|
| 469 |
with gr.Row():
|
| 470 |
with gr.Column():
|
| 471 |
+
mem_tipo = gr.Textbox(label="Tipo de Edificacao", placeholder="Ex: Escritorio comercial, Hotel, Escola")
|
| 472 |
+
mem_area = gr.Number(label="Area Total (m2)", value=200.0)
|
| 473 |
+
mem_pav = gr.Number(label="Pavimentos", value=1, step=1)
|
| 474 |
+
mem_cidade = gr.Textbox(label="Cidade", value="Goiania")
|
| 475 |
+
mem_resp = gr.Textbox(label="Responsavel Tecnico (Nome - CREA/CAU)")
|
| 476 |
+
mem_btn = gr.Button("Gerar Memorial", variant="primary")
|
| 477 |
+
with gr.Column():
|
| 478 |
+
mem_output = gr.Textbox(label="Memorial Descritivo", lines=30, show_copy_button=True)
|
| 479 |
+
mem_btn.click(gerar_memorial_func, inputs=[mem_tipo, mem_area, mem_pav, mem_cidade, mem_resp], outputs=mem_output)
|
| 480 |
+
|
| 481 |
+
# Tab 4: Auditoria
|
| 482 |
+
with gr.Tab("Auditoria de Projeto"):
|
| 483 |
+
gr.Markdown("### Audite seu projeto contra os requisitos da NT-01/2025")
|
| 484 |
+
with gr.Row():
|
| 485 |
+
with gr.Column():
|
| 486 |
+
audit_input = gr.Textbox(
|
| 487 |
+
label="Descreva seu projeto",
|
| 488 |
+
placeholder="Descreva os sistemas de seguranca previstos...",
|
| 489 |
+
lines=8
|
| 490 |
)
|
| 491 |
+
audit_btn = gr.Button("Auditar Projeto", variant="primary")
|
|
|
|
| 492 |
with gr.Column():
|
| 493 |
+
audit_output = gr.Textbox(label="Resultado da Auditoria", lines=20, show_copy_button=True)
|
| 494 |
+
audit_btn.click(auditar_projeto, inputs=audit_input, outputs=audit_output)
|
| 495 |
+
|
| 496 |
+
# Tab 5: SIAPI
|
| 497 |
+
with gr.Tab("Preparar SIAPI"):
|
| 498 |
+
gr.Markdown("### Prepare a documentacao para submissao no SIAPI/CBMGO")
|
| 499 |
with gr.Row():
|
| 500 |
with gr.Column():
|
| 501 |
+
siapi_tipo = gr.Textbox(label="Tipo de Edificacao")
|
| 502 |
+
siapi_area = gr.Number(label="Area Total (m2)", value=200.0)
|
| 503 |
+
siapi_resp = gr.Textbox(label="Nome do Responsavel Tecnico")
|
| 504 |
+
siapi_cpf = gr.Textbox(label="CPF do Responsavel (apenas numeros)", placeholder="00000000000")
|
| 505 |
+
siapi_reg = gr.Textbox(label="Registro Profissional (CREA/CAU)", placeholder="CREA-GO 12345-D")
|
| 506 |
+
siapi_btn = gr.Button("Preparar Documentacao", variant="primary")
|
|
|
|
|
|
|
|
|
|
| 507 |
with gr.Column():
|
| 508 |
+
siapi_output = gr.Textbox(label="Checklist de Submissao", lines=25, show_copy_button=True)
|
| 509 |
+
siapi_btn.click(preparar_siapi, inputs=[siapi_tipo, siapi_area, siapi_resp, siapi_cpf, siapi_reg], outputs=siapi_output)
|
| 510 |
+
|
| 511 |
+
# Tab 6: Sobre
|
| 512 |
+
with gr.Tab("Sobre o CERCON"):
|
| 513 |
gr.Markdown("""
|
| 514 |
+
## CERCON - Agente CBMGO
|
| 515 |
+
|
| 516 |
+
**Versao:** 1.0.0 | **Base normativa:** NT-01/2025 CBMGO
|
| 517 |
+
|
| 518 |
+
### Funcionalidades
|
| 519 |
+
- **Calculadora de Seguranca**: Calcula extintores, hidrantes, SPDA e sistemas obrigatorios
|
| 520 |
+
- **Consulta NT-01/2025**: RAG sobre normas de prevencao de incendio
|
| 521 |
+
- **Gerador de Memorial**: Cria memoriais PPCI conforme NT-01/2025
|
| 522 |
+
- **Auditoria de Projetos**: Verifica conformidade com as normas
|
| 523 |
+
- **Preparacao SIAPI**: Checklists para submissao ao CBMGO
|
| 524 |
+
|
| 525 |
+
### Tecnologia
|
| 526 |
+
- Interface: Gradio | Busca: FAISS + Sentence Transformers
|
| 527 |
+
- LLM: Llama-3.1-8B (com GPU) | Fallback: Regras declarativas (sem GPU)
|
| 528 |
+
- Repositorio: https://huggingface.co/carlosh10/CERCON
|
| 529 |
+
|
| 530 |
+
### Importante
|
| 531 |
+
Este agente e uma ferramenta de apoio tecnico. O PPCI oficial deve
|
| 532 |
+
sempre ser elaborado por profissional habilitado com ART/RRT.
|
| 533 |
+
|
| 534 |
+
**CBMGO**: www.bombeiros.go.gov.br | (62) 3201-5959
|
| 535 |
+
""")
|
| 536 |
|
| 537 |
if __name__ == "__main__":
|
| 538 |
demo.launch()
|