Created
May 6, 2025 23:48
-
-
Save engdiogenes/61c74d79bf9c2b27297eb0e769dd2e75 to your computer and use it in GitHub Desktop.
Gestao_energia_eletrica
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import streamlit as st | |
st.set_page_config(layout="wide") | |
from streamlit_autorefresh import st_autorefresh | |
st_autorefresh(interval=300000, key="auto_refresh") # Atualiza a cada 5 minutos | |
import pandas as pd | |
import io | |
import matplotlib.pyplot as plt | |
import json | |
import os | |
# --- Funções auxiliares --- | |
def limpar_valores(texto): | |
return texto.replace(",", "") | |
def carregar_dados(dados_colados): | |
dados = pd.read_csv(io.StringIO(limpar_valores(dados_colados)), sep="\t") | |
dados["Datetime"] = pd.to_datetime(dados["Date"] + " " + dados["Time"]) | |
dados = dados.sort_values("Datetime") | |
colunas_originais = [ | |
"MM_MPTF_QGBT-03_KWH.PresentValue", "MM_GAHO_QLFE-01-01_KWH.PresentValue", | |
"MM_MAIW_QGBT-GERAL_KWH.PresentValue", "MM_MPTF_QGBT-01_KWH.PresentValue", | |
"MM_MPTF_QGBT-02_KWH.PresentValue", "MM_MPTF_CEAG_KWH.PresentValue", | |
"MM_SEOB_QGBT-01-01_KWH.PresentValue", "MM_OFFI_QGBT-01_KWH.PresentValue", | |
"MM_EBPC_QLF-01-01_KWH.PresentValue", "KWH_PCCB_SEPAM-S40-01.PresentValue", | |
"MM_OFFI_QGBT-01-02_KWH.PresentValue" | |
] | |
novos_rotulos = { | |
"MM_MPTF_QGBT-03_KWH.PresentValue": "MP&L", | |
"MM_GAHO_QLFE-01-01_KWH.PresentValue": "GAHO", | |
"MM_MAIW_QGBT-GERAL_KWH.PresentValue": "MAIW", | |
"MM_MPTF_QGBT-01_KWH.PresentValue": "QGBT1-MPTF", | |
"MM_MPTF_QGBT-02_KWH.PresentValue": "QGBT2-MPTF", | |
"MM_MPTF_CEAG_KWH.PresentValue": "CAG", | |
"MM_SEOB_QGBT-01-01_KWH.PresentValue": "SEOB", | |
"MM_OFFI_QGBT-01_KWH.PresentValue": "OFFICE", | |
"MM_EBPC_QLF-01-01_KWH.PresentValue": "EBPC", | |
"KWH_PCCB_SEPAM-S40-01.PresentValue": "PCCB", | |
"MM_OFFI_QGBT-01-02_KWH.PresentValue": "PMDC-OFFICE" | |
} | |
dados = dados.rename(columns=novos_rotulos) | |
medidores = list(novos_rotulos.values()) | |
dados[medidores] = dados[medidores].astype(float) | |
consumo = dados[["Datetime"] + medidores].copy() | |
for col in medidores: | |
consumo[col] = consumo[col].diff().abs() | |
consumo = consumo.dropna() | |
consumo["TRIM&FINAL"] = consumo["QGBT1-MPTF"] + consumo["QGBT2-MPTF"] | |
consumo["OFFICE + CANTEEN"] = consumo["OFFICE"] - consumo["PMDC-OFFICE"] | |
consumo = consumo.drop(columns=["QGBT1-MPTF", "QGBT2-MPTF"]) | |
return consumo | |
# --- Menu lateral --- | |
pagina = st.sidebar.selectbox("Escolha a página:", [ | |
"Página Principal", "Gráficos por Medidor", "Limites de Consumo", "Dashboard" | |
]) | |
#st.title("Análise de Consumo de Energia (kWh)") | |
dados_colados = st.text_area("Cole os dados aqui (tabulados):", height=300) | |
if dados_colados: | |
try: | |
consumo = carregar_dados(dados_colados) | |
datas_disponiveis = consumo["Datetime"].dt.date.unique() | |
data_selecionada = st.selectbox("Selecione a data", sorted(datas_disponiveis, reverse=True)) | |
dados_dia = consumo[consumo["Datetime"].dt.date == data_selecionada] | |
if dados_dia.empty: | |
st.warning("Nenhum dado disponível para a data selecionada.") | |
st.stop() | |
horas = dados_dia["Datetime"].dt.hour | |
medidores_disponiveis = [col for col in dados_dia.columns if col != "Datetime"] | |
# Página 1 - Principal | |
if pagina == "Página Principal": | |
medidores_selecionados = st.multiselect("Selecione os medidores:", medidores_disponiveis, default=medidores_disponiveis) | |
fig, ax = plt.subplots(figsize=(16, 6)) | |
for medidor in medidores_selecionados: | |
ax.plot(horas, dados_dia[medidor], label=medidor) | |
if "limites_por_medidor" in st.session_state and medidor in st.session_state.limites_por_medidor: | |
ax.plot(range(24), st.session_state.limites_por_medidor[medidor], linestyle="--", color="red", label=f"Limite - {medidor}") | |
ax.set_title(f"Consumo horário em {data_selecionada} (kWh)") | |
ax.set_xlabel("Hora do dia") | |
ax.set_ylabel("Consumo (kWh)") | |
ax.set_xticks(range(0, 24)) | |
ax.legend(loc="lower center", bbox_to_anchor=(0.5, -0.4), ncol=3, fontsize='small') | |
plt.xticks(rotation=45) | |
st.pyplot(fig) | |
st.markdown("### Consumo Horário (kWh)") | |
st.dataframe( | |
dados_dia.set_index("Datetime")[medidores_selecionados].round(2).style.set_properties(**{"text-align": "center"}), | |
use_container_width=True | |
) | |
st.markdown("### Consumo Total por Medidor (kWh)") | |
totais = dados_dia[medidores_disponiveis].sum().round(2).to_frame(name="Consumo Total (kWh)") | |
st.dataframe(totais.style.set_properties(**{"text-align": "center"}), use_container_width=True) | |
# Página 2 - Gráficos por Medidor | |
elif pagina == "Gráficos por Medidor": | |
st.markdown("### Gráficos Individuais com Curva de Limite") | |
cores = plt.cm.get_cmap("tab10", len(medidores_disponiveis)) | |
for idx, medidor in enumerate(medidores_disponiveis): | |
fig, ax = plt.subplots(figsize=(12, 4)) | |
ax.plot(horas, dados_dia[medidor], label="Consumo", color=cores(idx)) | |
limite_total = 0 | |
consumo_total = dados_dia[medidor].sum() | |
if "limites_por_medidor" in st.session_state and medidor in st.session_state.limites_por_medidor: | |
limites = st.session_state.limites_por_medidor[medidor] | |
ax.plot(range(24), limites, label="Limite", linestyle="--", color="red") | |
limite_total = sum(limites) | |
ax.set_title(f"{medidor} - Consumo por hora (kWh)") | |
ax.set_xlabel("Hora do dia") | |
ax.set_ylabel("Consumo (kWh)") | |
ax.set_xticks(range(0, 24)) | |
ax.legend(fontsize='small') | |
st.pyplot(fig) | |
st.markdown(f"**Resumo - {medidor}**") | |
resumo_df = pd.DataFrame({ | |
"Soma dos Limites (kWh)": [round(limite_total, 2)], | |
"Soma do Consumo (kWh)": [round(consumo_total, 2)] | |
}, index=["Total"]) | |
def highlight_excesso(val): | |
consumo = resumo_df["Soma do Consumo (kWh)"].values[0] | |
limite = resumo_df["Soma dos Limites (kWh)"].values[0] | |
return ["", "background-color: red; color: white"] if consumo > limite else ["", ""] | |
styled = resumo_df.style.set_properties(**{"text-align": "center"}).apply(highlight_excesso, axis=1) | |
st.dataframe(styled, use_container_width=True) | |
# Página 3 - Configuração de Limites | |
elif pagina == "Limites de Consumo": | |
st.markdown("### Configure os limites por hora para cada medidor") | |
if "limites_por_medidor" not in st.session_state: | |
st.session_state.limites_por_medidor = {m: [5.0]*24 for m in medidores_disponiveis} | |
uploaded_file = st.file_uploader("Carregar limites a partir de um arquivo JSON", type="json") | |
if uploaded_file is not None: | |
try: | |
st.session_state.limites_por_medidor = json.load(uploaded_file) | |
st.success("Limites carregados com sucesso!") | |
except Exception as e: | |
st.error(f"Erro ao carregar limites: {e}") | |
for medidor in medidores_disponiveis: | |
st.markdown(f"#### {medidor}") | |
st.markdown(f"##### Limites por hora para {medidor}") | |
cols = st.columns(6) | |
novos_valores = [] | |
for i in range(24): | |
with cols[i % 6]: | |
valor = st.number_input( | |
f"{i}h", min_value=0.0, max_value=800.0, | |
value=float(st.session_state.limites_por_medidor.get(medidor, [5.0]*24)[i]), | |
step=0.5, key=f"{medidor}_{i}" | |
) | |
novos_valores.append(valor) | |
st.session_state.limites_por_medidor[medidor] = novos_valores | |
if st.button("Salvar limites horários"): | |
with open("limites_salvos.json", "w") as f: | |
json.dump(st.session_state.limites_por_medidor, f) | |
st.success("Limites salvos com sucesso!") | |
limites_json = json.dumps(st.session_state.limites_por_medidor, indent=2) | |
st.download_button("Download dos limites", data=limites_json, file_name="limites_por_medidor.json", mime="application/json") | |
# Página 4 - Dashboard | |
elif pagina == "Dashboard": | |
st.markdown("### Dashboard - Gráficos por Medidor") | |
cores = plt.cm.get_cmap("tab10", len(medidores_disponiveis)) | |
for i in range(0, len(medidores_disponiveis), 4): | |
cols = st.columns(4) | |
for j in range(4): | |
if i + j < len(medidores_disponiveis): | |
medidor = medidores_disponiveis[i + j] | |
with cols[j]: | |
fig, ax = plt.subplots(figsize=(5, 3)) | |
ax.plot(horas, dados_dia[medidor], label="Consumo", color=cores(i + j)) | |
if "limites_por_medidor" in st.session_state and medidor in st.session_state.limites_por_medidor: | |
limites = st.session_state.limites_por_medidor[medidor] | |
ax.plot(range(24), limites, label="Limite", linestyle="--", color="red") | |
ax.set_title(medidor) | |
ax.set_xticks(range(0, 24)) | |
ax.set_xlabel("Hora") | |
ax.set_ylabel("kWh") | |
ax.legend(fontsize="x-small") | |
st.pyplot(fig) | |
except Exception as e: | |
st.error(f"Erro ao processar os dados: {e}") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment