This commit is contained in:
Oscar Suescun Elizalde 2024-11-23 17:52:21 +01:00
commit f26a806b5d
14 changed files with 895 additions and 0 deletions

1
berry_USB.py Normal file
View File

@ -0,0 +1 @@
"""Aqui esta el main de la rasberri cuando funcione en modo USB"""

13
berry_server.py Normal file
View File

@ -0,0 +1,13 @@
from clase_cliente import Cliente
# Configuración del cliente y el servidor
SERVER_HOST = '127.0.0.1' # Asumimos localhost
SERVER_PORT = 65432 # Puerto de comunicación
# Ejecución del cliente
if __name__ == "__main__":
berry = Cliente(SERVER_HOST, SERVER_PORT)
berry.conectar()
while True:
berry.escuchar_y_responder()

72
clase_cliente.py Normal file
View File

@ -0,0 +1,72 @@
import socket, json
from lector import *
# Clase Cliente para la conexión y generación de ondas
class Cliente:
def __init__(self, host, port):
self.host = host
self.port = port
self.socket = None
def conectar(self):
"""Conecta al servidor de forma persistente"""
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.host, self.port))
print("Conectado al servidor")
except ConnectionError as e:
print(f"Error al conectar con el servidor: {e}")
def escuchar_y_responder(self):
"""Escucha solicitudes del servidor y responde con datos generados"""
try:
while True:
# Escucha de forma continua para recibir la solicitud de medición del servidor
print("Esperando solicitud de medición del servidor...")
data = self.socket.recv(1024)
if data:
print("Solicitud recibida del servidor:", data.decode('utf-8'))
request_vars = json.loads(data.decode('utf-8'))
if request_vars == 'Apagate':
break
self.mandar_datos(request_vars)
except Exception as e:
print(f"Error en la conexión con el servidor: {e}")
finally:
self.socket.close()
print("Conexión cerrada con el servidor")
def mandar_datos(self, request_vars):
"""Genera los datos de las ondas según las variables recibidas y los envía al servidor"""
fs = request_vars.get('Velocidad Muestreo', 1e3) # Frecuencia de muestreo en Hz, valor estandar 1e3
size = request_vars.get('Numero Muestras', 50) # Número de muestras, valor estandar 50
paquete = generar_paquete_ejemplo(fs, size)
# Envía los datos de vuelta al servidor
self.mandar_paquete(paquete)
def mandar_paquete(self, data):
"""Envía el JSON generado al servidor en la misma conexión"""
try:
json_data = json.dumps(data) + "\n" # Añadimos el delimitador al final del mensaje
self.socket.sendall(json_data.encode('utf-8'))
print("Datos enviados al servidor")
except Exception as e:
print(f"Error al enviar datos al servidor: {e}")

75
clase_ploteador.py Normal file
View File

@ -0,0 +1,75 @@
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from funciones_analisis import *
from scipy.fft import fft, fftfreq
class Ploteador_VI(FigureCanvas):
def __init__(self, t, V, I, Titulo = False, parent=None):
fig, self.ax = plt.subplots(figsize=(6,4))
super().__init__(fig)
self.setParent(parent)
self.x = t
self.y1 = V
self.y2 = I
self.linea_V, self.linea_I = plot_VI(self.ax, self.x, self.y1, self.y2, Titulo=Titulo)
def actualizar_plot(self, t, V, I):
self.linea_V.set_xdata(t)
self.linea_I.set_xdata(t)
self.linea_V.set_ydata(V)
self.linea_I.set_ydata(I)
self.ax.relim()
self.ax.autoscale()
self.draw()
class Ploteador_Termico(FigureCanvas):
def __init__(self, t, Temperatura1, Temperatura2, parent=None):
fig, self.ax = plt.subplots(figsize=(6,4))
super().__init__(fig)
self.setParent(parent)
self.x = t
self.y1 = Temperatura1
self.y2 = Temperatura2
self.linea_1 = plot_termico(self.ax, self.x, self.y1, tags = "Cobre, ",Titulo='Termico')
self.linea_2 = plot_termico(self.ax, self.x, self.y2, tags = "Hierro", reset_plot=False)
def actualizar_plot(self, t, Temperatura1, Temperatura2):
self.linea_1.set_xdata(t)
self.linea_2.set_xdata(t)
self.linea_1.set_ydata(Temperatura1)
self.linea_2.set_ydata(Temperatura2)
self.ax.relim()
self.ax.autoscale()
self.draw()
class Ploteador_fft(FigureCanvas):
def __init__(self, t, onda, fs, param, parent=None):
fig, self.ax = plt.subplots(figsize=(6,4))
super().__init__(fig)
self.setParent(parent)
self.linea = plot_fft(self.ax, t, onda, fs, Titulo = f"FFT de {param}")
def actualizar_plot(self, t, onda, fs, param):
x = fftfreq(len(t), 1/fs)[:len(t)//2]
y = 1/len(x) * np.abs(fft(onda)[0:len(t)//2])
self.linea.set_ydata(y)
self.linea.set_xdata(x)
self.ax.set_title(f"FFT de {param}")
self.ax.relim()
self.ax.autoscale()
self.draw()

102
clase_server.py Normal file
View File

@ -0,0 +1,102 @@
import socket, json
# Configuración del servidor
HOST = '127.0.0.1'
PORT = 65432
class Server:
def __init__(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((HOST, PORT))
self.server_socket.listen(1)
print("Esperando conexión del cliente...")
self.conn, addr = self.server_socket.accept()
print(f"Cliente conectado desde {addr}")
def apagar_cliente(self): # Funcion que manda orden de apagar cliente, util para desarrollo y debug
vars_request = "Apagate"
flag = True
while flag:
try:
json_data = json.dumps(vars_request) + "\n" # Añadimos el delimitador al final
self.conn.sendall(json_data.encode('utf-8'))
print("Orden de Apagado Enviada")
flag = False
except Exception as e:
print(f"Error al enviar orden de apagado:", {e})
break
# Función para enviar solicitudes de medición al cliente de forma continua
def pedir_datos(self, fs, size=50): #necesita la frecuencia de medida si o si, size tiene un valor base que se puede cambiar
"""Envia solicitudes de inicio al cliente cada f_request segundos"""
flag = True
while flag:
vars_request = {
"Velocidad Muestreo": fs,
"Numero Muestras": size
}
try:
json_data = json.dumps(vars_request) + "\n" # Añadimos el delimitador al final
self.conn.sendall(json_data.encode('utf-8'))
datos = self.escuchar_datos()
flag = False
return datos
except Exception as e:
print(f"Error al enviar solicitud de medición al cliente: {e}")
break
# Funcion que espera para escuchar datos
def escuchar_datos(self):
buffer_size = 4096 # Tamaño del búfer de recepción
data_buffer = "" # Almacena datos recibidos incompletos
flag = True
while flag: # solo acaba el bucle cuando un paquete ha sido recibido
try:
# Recibe el siguiente fragmento de datos
packet = self.conn.recv(buffer_size).decode('utf-8')
if not packet:
break # Desconexión del cliente
# Añade el fragmento al buffer de datos
data_buffer += packet
# Procesa cada mensaje JSON completo en el buffer
while "\n" in data_buffer: # Verifica si hay un delimitador en el buffer
json_message, data_buffer = data_buffer.split("\n", 1) # Separa el mensaje completo
try:
# Decodifica el mensaje JSON completo
received_data = json.loads(json_message)
flag = False
return received_data
except json.JSONDecodeError as e:
print(f"Error al decodificar datos JSON: {e}")
except (ConnectionResetError, ConnectionAbortedError) as e:
print("La conexión con el cliente se cerró abruptamente:", e)
break
except Exception as e:
print(f"Error inesperado al recibir datos del cliente: {e}")
break

1
clase_usb.py Normal file
View File

@ -0,0 +1 @@
"""Este script se encarga de la comunicacion entre berry y ordenador por USB"""

9
comprobar_modo.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
if ls /dev/ttyACM* 1>/dev/null 2>&1; then
echo "USB detectado"
python3 /ruta/a/berry_usb.py
else
echo "USB no detectado, mandando al server"
python3 /ruta/a/berry_server.py
fi

184
funciones_analisis.py Normal file
View File

@ -0,0 +1,184 @@
import numpy as np
import pandas as pd
import os, shutil
from scipy.fft import fft, fftfreq
def crear_cache():
try:
os.makedirs('temp/T1')
os.makedirs('temp/T2')
os.makedirs('temp/Tiempo')
except FileExistsError:
shutil.rmtree('temp')
os.makedirs('temp/T1')
os.makedirs('temp/T2')
os.makedirs('temp/Tiempo')
def plot_VI(ax, t, V, I, analisis = False, Titulo = False): #parametro reset plot sirve para dar la opcion a superponer graficas
linea_V, = ax.plot(t, V, label="Tension") # Graficar la Tension
linea_I, = ax.plot(t, I, label="Corriente") # Graficar la Corriente
ax.set_ylabel('Amplitud')
ax.set_xlabel('Tiempo [ms]')
ax.grid(True)
if Titulo: ax.set_title(Titulo) #si hay un titulo que lo ponga
ax.legend(loc='upper right')
if analisis:
V_rms, I_rms, FP, tipo_FP = analizar_ondas(V,I)
data = [f"Tension RMS: {V_rms}[V]", f"Corriente RMS: {I_rms}[A]", f"FP: {FP} {tipo_FP}"]
for i, text in enumerate(data):
ax.text(1.05, 0.8 - i*0.1, text, fontsize=12, ha='left', va='center', transform=ax.transAxes)
return linea_V, linea_I
def plot_termico(ax, t, T, reset_plot = True, tags = False, Titulo = False):
if reset_plot: ax.clear() # que limpie la grafica
if Titulo: ax.set_title(Titulo) #que ponga un titulo si lo hay
linea, = ax.plot(t, T, label = tags) # Graficar temperatura
ax.set_ylabel('Temperatura [ºC]')
ax.set_xlabel('Tiempo [s]')
ax.grid(True)
if tags: ax.legend(loc='upper right')
return linea
def plot_fft(ax, t, onda, fs, threshold_picos = False, reset_plot = False, Titulo = False, tags = False):
if reset_plot: ax.clear() # que limpie la grafica
if Titulo: ax.set_title(Titulo) #que ponga un titulo si lo hay
x = fftfreq(len(t), 1/fs)[:len(t)//2]
y = 1/len(x) * np.abs(fft(onda)[0:len(t)//2])
linea, = ax.plot(x,y)
ax.set_ylabel('Amplitud')
ax.set_xlabel('Frecuencias')
if threshold_picos:
peaks = [(freq, amp) for freq, amp in zip(x, y) if amp > threshold_picos]
for freq, amp in peaks:
ax.annotate(f"{freq:.2f} Hz\n Amplitud: {amp:.2f}",
xy =(freq, amp),
xytext=(freq, amp +.05),
fontsize=10,
ha="left",
va = 'center')
ax.set_xlim(left=min(x), right=max(x) + 10)
ax.set_ylim(bottom=0, top=max(y) + 0.2)
if tags: ax.legend(loc='upper right')
return linea
def analizar_ondas(V, I):
V_rms = round(np.sqrt(np.mean(np.array(V)**2)))
I_rms = round(np.sqrt(np.mean(np.array(I)**2)))
V = fft(V)
I = fft(I)
idx = np.argmax(np.abs(V))
fase_1 = np.angle(V[idx])
fase_2 = np.angle(I[idx])
desfase = fase_2 - fase_1
tipo_desfase = 'Inductivo'
if desfase > 0:
tipo_desfase = 'Capacitivo'
factor_potencia = round(np.cos(abs(desfase)),2)
return V_rms, I_rms, factor_potencia, tipo_desfase
def guardar_todo(datos_temp, datos_electricos):
print('Guardando Archivos')
guardar_temperatura_npy(datos_temp['Tiempo'], datos_temp['T1'], datos_temp['T2'])
guardar_temperatura()
guardar_VI(datos_electricos['V1'], datos_electricos['I1'], datos_electricos['V2'], datos_electricos['I2'])
shutil.rmtree('temp') #borro chache
print('Archivos Guardados')
def guardar_temperatura_npy(Tiempo, T1, T2):
n = len(os.listdir('temp/Tiempo'))
np.save(f"temp/Tiempo/{n}.npy", Tiempo)
np.save(f"temp/T1/{n}.npy", T1)
np.save(f"temp/T2/{n}.npy", T2)
def guardar_temperatura(): # Mira los datos del directorio temp y guarda los datos de temperatura en un csv
try: os.makedirs('Resultados/Termicos')
except:pass
elementos = os.listdir('temp')
data = []
for i in elementos:
temp = [0]
for j in os.listdir(f"temp/{i}"):
temp = np.concatenate((temp, np.load(f"temp/{i}/{j}")))
data.append(temp[-(len(temp)-1):])
data = np.array(data)
df = pd.DataFrame(np.transpose(data), columns= elementos)
n = len(os.listdir('Resultados/Termicos')) + 1
df.to_csv(f"Resultados/Termicos/Datos_Termicos_{n}.csv", index=False)
def guardar_VI(V1, I1, V2, I2): # guarda los utimos datos electricos en un csv
try:os.makedirs('Resultados/Electricos')
except:pass
data = np.array([V1, I1, V2, I2])
columnas = ['Tension Primario [V]', 'Corriente Primario [A]', 'Tension Secundario [V]', 'Corriente Secundario [A]']
df = pd.DataFrame(np.transpose(data), columns = columnas)
n = len(os.listdir('Resultados/Termicos')) + 1
df.to_csv(f'Resultados/Electricos/Datos_Electricos_{n}.csv')

26
lector.py Normal file
View File

@ -0,0 +1,26 @@
import numpy as np
import random
def generar_paquete_ejemplo(fs, size):
t = np.arange(0, size/fs, 1/fs)
# Generación de las ondas
V1 = 200 * np.sin(2 * np.pi * 50 * t ) + 100 * np.sin(2 * np.pi * 100 * t) + 50 * np.sin(2 * np.pi * 150 * t) + 10*np.random.normal(0,1,size= size)
I1 = 30* np.sin(2 * np.pi * 50 * t + np.radians(60)) + 10*np.random.normal(0,1,size= size) # Desfase de 90º
V2 = 200 * np.sin(2 * np.pi * 50 * t + np.radians(random.randint(0,90))) + 10*np.random.normal(0,1,size= size) # Desfase de 30º con V1
I2 = 30* np.sin(2 * np.pi * 50 * t + np.radians(random.randint(0,90))) + 10*np.random.normal(0,1,size= size)# Desfase de 30º con I1 y 90º de V1
T1 = 3*t*random.randint(0,3)
T2 = 2*t
# Empaquetado en Diccionario
data = {
"V1": np.array(V1.tolist()),
"V2": np.array(V2.tolist()),
"I1": np.array(I1.tolist()),
"I2": np.array(I2.tolist()),
"T1": np.array(T1.tolist()),
"T2": np.array(T2.tolist())
}
return data

334
main_ordenador.py Normal file
View File

@ -0,0 +1,334 @@
import sys
from lector import *
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QGridLayout
from PyQt5.QtWidgets import QLabel, QLineEdit, QPushButton
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QFont
from clase_ploteador import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Analizador")
self.setGeometry(0, 0, 1000, 800)
self.center_window()
central_widget = QWidget()
self.setCentralWidget(central_widget)
font = QFont('Arial',14)
central_widget.setFont(font)
layout = QHBoxLayout()
layout_parametros = QVBoxLayout()
layout_graficas = QGridLayout()
self.fs = 1000
self.buff = 100
self.act = 500
self.mult_V1 = 1
self.mult_I1 = 1
self.mult_V2 = 1
self.mult_I2 = 1
self.selec_fft = 'V1'
layout_parametros = self.modulo_botones(layout_parametros)
layout_graficas = self.modulo_graficas(layout_graficas)
layout.addLayout(layout_graficas)
layout.addLayout(layout_parametros)
layout.setStretchFactor(layout_graficas, 6)
layout.setStretchFactor(layout_parametros, 1)
central_widget.setLayout(layout)
def center_window(self):
screen = QApplication.primaryScreen()
frame_geom = self.frameGeometry()
screen_center = screen.availableGeometry().center()
frame_geom.moveCenter(screen_center)
self.move(frame_geom.topLeft())
def modulo_botones(self, layout):
self.label_fs = QLabel("Fecuencia Medida: 1 kHz")
self.label_buff= QLabel("Tamaño de Paquete Datos: 100")
self.label_act= QLabel("Frecuencia Actualizacion Graficos: 2 fps")
self.label_V1= QLabel("Multiplicador Tension 1º: 1")
self.label_I1= QLabel("Multiplicador Corriente 1º: 1")
self.label_V2= QLabel("Multiplicador Tension 2º: 1")
self.label_I2= QLabel("Multiplicador Corriente 2º: 1")
self.input_fs = QLineEdit()
self.input_fs.setPlaceholderText('Frecuencia de medida')
self.input_buff = QLineEdit()
self.input_buff.setPlaceholderText('Tamaño del Paquete')
self.input_act = QLineEdit()
self.input_act.setPlaceholderText('Frecuencia de Actualizacion')
self.input_V1 = QLineEdit()
self.input_V1.setPlaceholderText('Multiplicador Tension 1º')
self.input_I1 = QLineEdit()
self.input_I1.setPlaceholderText('Multiplicador Corriente 1º')
self.input_V2 = QLineEdit()
self.input_V2.setPlaceholderText('Multiplicador Tension 2º')
self.input_I2 = QLineEdit()
self.input_I2.setPlaceholderText('Multiplicador Corriente 2º')
self.update_button = QPushButton('Actualizar Medidas')
self.update_button.clicked.connect(self.actualizar_metodo_medida)
self.update_button = QPushButton('Actualizar Medidas')
self.update_button.clicked.connect(self.actualizar_metodo_medida)
layout.addWidget(self.label_fs)
layout.addWidget(self.input_fs)
layout.addWidget(self.label_buff)
layout.addWidget(self.input_buff)
layout.addWidget(self.label_act)
layout.addWidget(self.input_act)
layout.addWidget(self.label_V1)
layout.addWidget(self.input_V1)
layout.addWidget(self.label_I1)
layout.addWidget(self.input_I1)
layout.addWidget(self.label_V2)
layout.addWidget(self.input_V2)
layout.addWidget(self.label_I2)
layout.addWidget(self.input_I2)
layout.addWidget(self.update_button)
layout.setAlignment(Qt.AlignRight)
return layout
def actualizar_metodo_medida(self):
if self.input_fs.text():
temp = self.input_fs.text()
try:
self.fs = float(temp) * 1000 #Guardo el Valor
self.label_fs.setText(f"Fecuencia Medida: {temp} kHz")
except: self.label_fs.setText(f"Fecuencia Medida: ¡No valido!")
if self.input_buff.text():
temp = self.input_buff.text()
try:
self.buff = int(temp) # guardo el valor
self.label_buff.setText(f"Tamaño de Paquete Datos: {temp}")
except: self.label_buff.setText(f"Tamaño de Paquete Datos: ¡No valido!")
if self.input_act.text():
temp = self.input_act.text()
self.act = 1000/float(temp)
try:
if self.act >= self.buff/self.fs:
self.act = temp # guardo el valor
self.label_act.setText(f"Frecuencia Actualizacion Graficos: {temp} fps")
else: self.label_act.setText(f"Frecuencia Actualizacion Graficos: ¡No valido!")
except: self.label_act.setText(f"Frecuencia Actualizacion Graficos: ¡No valido!")
if self.input_V1.text():
temp = self.input_V1.text()
try:
self.mult_V1 = float(temp) # guardo el valor
self.label_V1.setText(f"Multiplicador Tension 1º: {temp}")
except: self.label_V1.setText("Multiplicador Tension 1º: ¡No valido!")
if self.input_I1.text():
temp = self.input_I1.text()
try:
self.mult_I1 = float(temp) # guardo el valor
self.label_I1.setText(f"Multiplicador Corriente 1º: {temp}")
except: self.label_I1.setText("Multiplicador Corriente 1º: ¡No valido!")
if self.input_V2.text():
temp = self.input_V2.text()
try:
self.mult_V2 = float(temp) # guardo el valor
self.label_V2.setText(f"Multiplicador Tension 2º: {temp}")
except: self.label_V2.setText("Multiplicador Tension 2º: ¡No valido!")
if self.input_I2.text():
temp = self.input_I2.text()
try:
self.mult_I2 = float(temp) # guardo el valor
self.label_I2.setText(f"Multiplicador Corriente 2º: {temp}")
except: self.label_I2.setText("Multiplicador Corriente 2º: ¡No valido!")
self.input_fs.clear()
self.input_buff.clear()
self.input_act.clear()
self.input_V1.clear()
self.input_I1.clear()
self.input_V2.clear()
self.input_I2.clear()
def modulo_seleccionador_fft(self, layout):
self.boton_fft_V1 = QPushButton("Tension 1")
self.boton_fft_I1 = QPushButton("Corriente 1")
self.boton_fft_V2 = QPushButton("Tension 2")
self.boton_fft_I2 = QPushButton("Corriente 2")
self.boton_fft_V1.clicked.connect(lambda:self.seleccion_fft('V1'))
self.boton_fft_I1.clicked.connect(lambda:self.seleccion_fft('I1'))
self.boton_fft_V2.clicked.connect(lambda:self.seleccion_fft('V2'))
self.boton_fft_I2.clicked.connect(lambda:self.seleccion_fft('I2'))
layout.addWidget(self.boton_fft_V1)
layout.addWidget(self.boton_fft_I1)
layout.addWidget(self.boton_fft_V2)
layout.addWidget(self.boton_fft_I2)
return layout
def seleccion_fft(self, seleccion):
self.selec_fft = seleccion
def modulo_graficas(self, layout):
datos = generar_paquete_ejemplo(self.fs, self.buff)
tiempo = np.arange(0, self.buff/self.fs, 1/self.fs)
# Crear Layout Primero
layout_primario_main = QVBoxLayout()
layout_analisis_1 = QHBoxLayout()
V, I, FP, tipo = analizar_ondas(datos['V1'], datos['I1'])
self.label_V1rms = QLabel(f'V_rms = {V}V')
self.label_I1rms = QLabel(f'I_rms = {I}A')
self.label_FP1 = QLabel(f'PF = {FP} {tipo}')
layout_analisis_1.addWidget(self.label_V1rms)
layout_analisis_1.addWidget(self.label_I1rms)
layout_analisis_1.addWidget(self.label_FP1)
self.primario = Ploteador_VI(t=tiempo, V = datos['V1'], I = datos['I1'], Titulo = 'VI Primario')
layout_primario_main.addWidget(self.primario)
layout_primario_main.addLayout(layout_analisis_1)
layout_primario_main.setStretchFactor(self.primario, 8)
layout_primario_main.setStretchFactor(layout_analisis_1, 1)
# Crear Layout Secundario
layout_secundario_main = QVBoxLayout()
layout_analisis_2 = QHBoxLayout()
V, I, FP, tipo = analizar_ondas(datos['V2'], datos['I2'])
self.label_V2rms = QLabel(f'V_rms = {V}V')
self.label_I2rms = QLabel(f'I_rms = {I}A')
self.label_FP2 = QLabel(f'PF = {FP} {tipo}')
layout_analisis_2.addWidget(self.label_V2rms)
layout_analisis_2.addWidget(self.label_I2rms)
layout_analisis_2.addWidget(self.label_FP2)
self.secundario = Ploteador_VI(t=tiempo, V = datos['V2'], I = datos['I2'], Titulo= 'VI Secundario')
layout_secundario_main.addWidget(self.secundario)
layout_secundario_main.addLayout(layout_analisis_2)
layout_secundario_main.setStretchFactor(self.secundario, 8)
layout_secundario_main.setStretchFactor(layout_analisis_2, 1)
# Crear Layout del Termico
self.termico = Ploteador_Termico(t=tiempo, Temperatura1=datos['T1'], Temperatura2=datos['T2'])
# crear layout de la fft
layout_fft_main = QVBoxLayout()
layout_fft_selector = QHBoxLayout()
layout_fft_selector = self.modulo_seleccionador_fft(layout_fft_selector)
self.fourier = Ploteador_fft(t=tiempo, onda = datos[self.selec_fft], fs = self.fs, param= self.selec_fft)
layout_fft_main.addWidget(self.fourier)
layout_fft_main.addLayout(layout_fft_selector)
# Agregar los widgets de gráficos al layout de la cuadrícula
layout.addLayout(layout_primario_main, 0, 0)
layout.addLayout(layout_secundario_main, 0, 1)
layout.addWidget(self.termico, 1, 0)
layout.addLayout(layout_fft_main, 1, 1)
layout.setRowStretch(0,1)
layout.setRowStretch(1,1)
# Configurar el temporizador para actualizar las gráficas en tiempo real
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_graphs)
self.timer.start(self.act) # Actualiza plots
return layout
def update_graphs(self):
# Generar nuevos datos en tiempo real (puedes reemplazar con datos reales)
datos = generar_paquete_ejemplo(self.fs, self.buff)
tiempo = np.arange(0, self.buff/self.fs, 1/self.fs)
# Actualizar cada gráfico
self.primario.actualizar_plot(tiempo, self.mult_V1 * datos['V1'], self.mult_I1 * datos['I1'])
self.secundario.actualizar_plot(tiempo, self.mult_V2 * datos['V2'], self.mult_I2 * datos['I2'])
self.termico.actualizar_plot(tiempo, datos['T1'], datos['T2'])
self.fourier.actualizar_plot(tiempo, datos[self.selec_fft], self.fs, self.selec_fft)
# Actualizar Los analisis
V, I, FP, tipo = analizar_ondas(datos['V1'], datos['I1'])
self.label_V1rms.setText(f"Vrms = {V} V")
self.label_I1rms.setText(f"Irms = {I} A")
self.label_FP1.setText(f"FP = {FP} {tipo}")
V, I, FP, tipo = analizar_ondas(datos['V2'], datos['I2'])
self.label_V2rms.setText(f"Vrms = {V} V")
self.label_I2rms.setText(f"Irms = {I} A")
self.label_FP2.setText(f"FP = {FP} {tipo}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

29
main_server.py Normal file
View File

@ -0,0 +1,29 @@
import matplotlib.pyplot as plt
import numpy as np
from funciones_analisis import *
from clase_server import Server
# Ejecución del servidor
if __name__ == "__main__":
frecuencia_sampling = 1e3 # velocidad muestreo
tamaño_paquete = 100 #
t = np.arange(0,tamaño_paquete/frecuencia_sampling, 1/frecuencia_sampling)
servidor = Server() # activo el servidor
datos = servidor.pedir_datos(fs= frecuencia_sampling, size= tamaño_paquete)
fig, ax = plt.subplots(1,1)
plot_fft(ax, t, datos['V1'], fs=frecuencia_sampling, threshold_picos=0.1)
plt.tight_layout()
plt.show()
servidor.apagar_cliente() # para debug esto hay que quitar

5
pyvenv.cfg Normal file
View File

@ -0,0 +1,5 @@
home = C:\Users\osuescuneli\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0
include-system-site-packages = false
version = 3.11.9
executable = C:\Users\osuescuneli\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\python.exe
command = C:\Users\osuescuneli\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\python.exe -m venv C:\Users\osuescuneli\Desktop\Analizador_Trafos

BIN
requirements.txt Normal file

Binary file not shown.

44
test.py Normal file
View File

@ -0,0 +1,44 @@
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel
class SelectorOpciones(QWidget):
def __init__(self):
super().__init__()
# Configurar la ventana
self.setWindowTitle("Seleccionador de Opciones")
self.setGeometry(100, 100, 300, 200)
# Layout principal
layout = QHBoxLayout()
# Crear botones para las opciones
self.resultado = QLabel("Selecciona una opción")
self.boton1 = QPushButton("Opción 1")
self.boton2 = QPushButton("Opción 2")
self.boton3 = QPushButton("Opción 3")
self.boton4 = QPushButton("Opción 4")
# Conectar los botones a una función
self.boton1.clicked.connect(lambda: self.mostrar_seleccion("Opción 1"))
self.boton2.clicked.connect(lambda: self.mostrar_seleccion("Opción 2"))
self.boton3.clicked.connect(lambda: self.mostrar_seleccion("Opción 3"))
self.boton4.clicked.connect(lambda: self.mostrar_seleccion("Opción 4"))
# Agregar botones al layout
layout.addWidget(self.boton1)
layout.addWidget(self.boton2)
layout.addWidget(self.boton3)
layout.addWidget(self.boton4)
layout.addWidget(self.resultado)
# Establecer layout
self.setLayout(layout)
def mostrar_seleccion(self, texto):
self.resultado.setText(f"Seleccionaste: {texto}")
if __name__ == "__main__":
app = QApplication([])
ventana = SelectorOpciones()
ventana.show()
app.exec_()