Commit 0ce79c90 by Alex

Proyecto funcionando

parent 2263309b
...@@ -6,6 +6,7 @@ import { startWith, switchMap } from 'rxjs/operators'; ...@@ -6,6 +6,7 @@ import { startWith, switchMap } from 'rxjs/operators';
import { CrearPedidoDialogComponent } from './crear-pedido-dialog/crear-pedido-dialog.component'; import { CrearPedidoDialogComponent } from './crear-pedido-dialog/crear-pedido-dialog.component';
import { MapaComponent } from './mapa/mapa.component'; // Importa MapaComponent import { MapaComponent } from './mapa/mapa.component'; // Importa MapaComponent
import { BackendService } from './backend.service'; import { BackendService } from './backend.service';
import { ServicioPedidoService } from './servicio-pedido.service'; // Asegúrate de tener este servicio
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
...@@ -15,16 +16,23 @@ import { BackendService } from './backend.service'; ...@@ -15,16 +16,23 @@ import { BackendService } from './backend.service';
export class AppComponent implements OnInit, OnDestroy { export class AppComponent implements OnInit, OnDestroy {
private subscription: Subscription = new Subscription(); //Variable para suscribirse a un topic private subscription: Subscription = new Subscription(); //Variable para suscribirse a un topic
private finalizaSubscription: Subscription = new Subscription();
private publishInterval: Subscription = new Subscription(); //Variable para publicar datos cada 10 segundos private publishInterval: Subscription = new Subscription(); //Variable para publicar datos cada 10 segundos
message: string = ''; //Variable para mostrar el mensaje MQTT //0202000105030705000200041109060110031000000200080101100110000106010701
message: string = '0202000105030705000200041109060110031000000200080101100110000106010701'; //Variable para mostrar el mensaje MQTT
@ViewChild(MapaComponent) mapaComponent!: MapaComponent; @ViewChild(MapaComponent) mapaComponent!: MapaComponent;
@ViewChild(CrearPedidoDialogComponent) pedidodialog!: CrearPedidoDialogComponent;
private ultimoIdDestino: number = 30;
constructor(public dialog: MatDialog, private mqttService: MqttService, private backendService:BackendService) {} constructor(public dialog: MatDialog, private mqttService: MqttService, private backendService:BackendService, private pedidoService: ServicioPedidoService) {}
ngOnInit() { ngOnInit() {
this.subscribeToTopic(); //Nos suscribimos al inicializar la aplicación this.subscribeToTopic(); //Nos suscribimos al inicializar la aplicación
this.startPublishing(); //Publicamos datos cada 10 segundos this.startPublishing(); //Publicamos datos cada 10 segundos
this.subscribeToFinaliza();
} }
ngOnDestroy() { ngOnDestroy() {
...@@ -41,19 +49,33 @@ export class AppComponent implements OnInit, OnDestroy { ...@@ -41,19 +49,33 @@ export class AppComponent implements OnInit, OnDestroy {
subscribeToTopic() { subscribeToTopic() {
console.log('Conectado:'); console.log('Conectado:');
this.subscription = this.mqttService.observe('mapa').subscribe((data: IMqttMessage) => { this.subscription = this.mqttService.observe('map').subscribe((data: IMqttMessage) => {
const message = data.payload.toString(); const messageMQTT = data.payload.toString();
console.log('Mensaje MQTT recibido:', message); console.log('Mensaje MQTT recibido:', messageMQTT);
this.backendService.enviarMapa(message).then((output:string) => { this.backendService.enviarMapa(messageMQTT).then((output:string) => {
console.log('Respuesta del servidor:', output) console.log('Respuesta del servidor:', output)
}); });
// Update mapStr in MapaComponent // Update mapStr in MapaComponent
this.mapaComponent.mapStr = message; this.mapaComponent.mapStr = messageMQTT;
this.message = messageMQTT;
// Call ngOnInit in MapaComponent to refresh the map // Call ngOnInit in MapaComponent to refresh the map
this.mapaComponent.ngOnInit(); this.mapaComponent.ngOnInit();
}); });
} }
subscribeToFinaliza() {
this.finalizaSubscription = this.mqttService.observe('finalizacion').subscribe({
next: (message) => {
console.log('Robot ha finalizado el pedido:', message.payload.toString());
this.procesarFinalizacionPedido();
},
error: (error) => console.error('Error al recibir mensaje de finalización:', error)
});
}
procesarFinalizacionPedido() {
this.pedidoService.finalizarPedidoEnCurso();
console.log('Primer pedido eliminado, siguiente pedido en la cola.');
}
/** /**
* Inicia la publicación periódica de mensajes en el topic 'pruebaMQTT'. * Inicia la publicación periódica de mensajes en el topic 'pruebaMQTT'.
* Se configura un intervalo que publica un mensaje cada 10 segundos, el cual incluye * Se configura un intervalo que publica un mensaje cada 10 segundos, el cual incluye
...@@ -69,14 +91,64 @@ startPublishing() { ...@@ -69,14 +91,64 @@ startPublishing() {
}) })
).subscribe(); ).subscribe();
} }
abrirPopupCrearPedido(): void { abrirPopupCrearPedido(): void {
const dialogRef = this.dialog.open(CrearPedidoDialogComponent, { const dialogRef = this.dialog.open(CrearPedidoDialogComponent, {
width: '1100px', width: '1100px',
height: '830px', height: '830px',
data: { mapaString: this.message }
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result) {
console.log('Datos del pedido cerrado:', result);
// Enviamos los caminos usando el último id de destino actual antes de actualizarlo.
this.enviarCaminos(this.ultimoIdDestino, result.idRecogida, result.idEntrega);
// Actualizamos el último id de destino al nuevo punto de entrega después de enviar los caminos.
this.actualizarUltimoIdDestino(result.idEntrega);
}
console.log('El diálogo se ha cerrado'); console.log('El diálogo se ha cerrado');
}); });
} }
actualizarUltimoIdDestino(nuevoDestinoId: number) {
this.ultimoIdDestino = nuevoDestinoId;
}
enviarCaminos(actual: number, paquete: number, destino: number) {
this.backendService.enviarCaminos(actual, paquete, destino).then(response => {
console.log('Caminos recibidos:', response);
// Transformación del array a string
const caminosString = this.formatearYQuitarUltimo(response);
console.log('Caminos formateados:', caminosString);
// Envío del mensaje formateado al broker MQTT
this.enviarMensajeMQTT(caminosString);
}).catch(error => {
console.error('Error al obtener los caminos:', error);
});
}
/**
* Convierte un array de arrays de números a un string en el formato "31,26,25;26,21,16,15".
* @param caminos Array de arrays de números que representan los caminos.
*/
formatearYQuitarUltimo(caminos: number[][]): string {
let caminosFormateados = caminos.map(camino => {
if (camino.length > 1) camino.pop(); // Quita el último elemento si hay más de uno
return camino.join(',');
}).join(';');
return caminosFormateados;
}
/**
* Publica un mensaje en el topic MQTT.
* @param mensaje El mensaje a publicar.
*/
enviarMensajeMQTT(mensaje: string) {
this.mqttService.publish('equipoD/pedido', mensaje).subscribe({
next: () => console.log('Mensaje MQTT enviado:', mensaje),
error: (error) => console.error('Error al enviar mensaje MQTT:', error)
});
}
} }
...@@ -14,8 +14,8 @@ import { HttpClientModule } from '@angular/common/http'; ...@@ -14,8 +14,8 @@ import { HttpClientModule } from '@angular/common/http';
// Configuración de MQTT // Configuración de MQTT
export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = { export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
hostname: '192.168.0.45', //Nombre de host o ip hostname: '192.168.48.245', //Nombre de host o ip
port: 9001, // Puerto de conexión port: 8083, // Puerto de conexión
path: '/mqtt', path: '/mqtt',
protocol: 'ws' // Usar 'wss' para conexiones seguras protocol: 'ws' // Usar 'wss' para conexiones seguras
}; };
......
...@@ -32,11 +32,11 @@ export class BackendService { ...@@ -32,11 +32,11 @@ export class BackendService {
} }
//todo enviarCaminos(actual: number, paquete: number, destino: number): Promise<any> {
enviarCaminos(ruta: string,): Promise<any> { const url = `${this.baseUrl}getcaminos?actual=${encodeURIComponent(actual.toString())}&paquete=${encodeURIComponent(paquete.toString())}&destino=${encodeURIComponent(destino.toString())}`;
const url = this.baseUrl + "getcaminos?actual=" + encodeURIComponent(ruta);
const response = this.http.get(url).toPromise(); const response = this.http.get(url).toPromise();
console.log("Respuesta sobre la ruta" + response); console.log("Respuesta sobre la ruta", response);
return response; return response;
} }
} }
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<!-- Contenedor del mapa --> <!-- Contenedor del mapa -->
<div class="map-area"> <div class="map-area">
<app-mapa [interactivo]="true" (celdaSeleccionada)="enCeldaSeleccionada($event)"></app-mapa> <app-mapa [mapStr]="mapaString" [interactivo]="true" (celdaSeleccionada)="enCeldaSeleccionada($event)"></app-mapa>
</div> </div>
</div> </div>
import { Component } from '@angular/core'; import { Component, Inject, Input } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ServicioPedidoService } from '../servicio-pedido.service' import { ServicioPedidoService } from '../servicio-pedido.service'
import { Pedido } from '../pedido.model'; // Ajusta la ruta del import según tu estructura import { Pedido } from '../pedido.model'; // Ajusta la ruta del import según tu estructura
import { MatDialogRef } from '@angular/material/dialog';
@Component({ @Component({
...@@ -16,10 +18,16 @@ import { Pedido } from '../pedido.model'; // Ajusta la ruta del import según tu ...@@ -16,10 +18,16 @@ import { Pedido } from '../pedido.model'; // Ajusta la ruta del import según tu
* Se comunica con el servicio de pedidos para añadir los pedidos generados a la cola. * Se comunica con el servicio de pedidos para añadir los pedidos generados a la cola.
*/ */
export class CrearPedidoDialogComponent { export class CrearPedidoDialogComponent {
puntoDeRecogida: {id: string, row: number, col: number} | null = null; @Input() mapaString: string = '';
puntoDeEntrega: {id: string, row: number, col: number} | null = null; puntoDeRecogida: {idUnico: number,id: string, row: number, col: number} | null = null;
puntoDeEntrega: {idUnico:number,id: string, row: number, col: number} | null = null;
constructor(private pedidoService: ServicioPedidoService, private dialogRef: MatDialogRef<CrearPedidoDialogComponent>
,@Inject(MAT_DIALOG_DATA) public data: any,
) {
this.mapaString = data.mapaString; // Aquí se asigna el string recibido al campo mapaString
}
constructor(private pedidoService: ServicioPedidoService) {}
/** /**
* @brief Maneja la selección de un bloque en el mapa. * @brief Maneja la selección de un bloque en el mapa.
...@@ -29,7 +37,7 @@ constructor(private pedidoService: ServicioPedidoService) {} ...@@ -29,7 +37,7 @@ constructor(private pedidoService: ServicioPedidoService) {}
* *
* @param event Objeto que contiene el ID del bloque y sus coordenadas de fila y columna. * @param event Objeto que contiene el ID del bloque y sus coordenadas de fila y columna.
*/ */
enCeldaSeleccionada(event: {id: string, row: number, col: number}): void { enCeldaSeleccionada(event: {idUnico:number,id: string, row: number, col: number}): void {
if (!this.puntoDeRecogida) { if (!this.puntoDeRecogida) {
this.puntoDeRecogida = event; this.puntoDeRecogida = event;
// Actualiza los estilos de resaltado aquí si es necesario // Actualiza los estilos de resaltado aquí si es necesario
...@@ -66,14 +74,25 @@ constructor(private pedidoService: ServicioPedidoService) {} ...@@ -66,14 +74,25 @@ constructor(private pedidoService: ServicioPedidoService) {}
* Utiliza el servicio de pedidos para agregar el nuevo pedido generado con un ID único a la cola de pedidos. * Utiliza el servicio de pedidos para agregar el nuevo pedido generado con un ID único a la cola de pedidos.
*/ */
confirmarSeleccion(): void { confirmarSeleccion(): void {
console.log('Confirmación de selección con:', this.puntoDeRecogida, this.puntoDeEntrega);
if (this.puntoDeRecogida && this.puntoDeEntrega) { if (this.puntoDeRecogida && this.puntoDeEntrega) {
const nuevoPedido: Pedido = { const nuevoPedido: Pedido = {
id: '', id: '', // Asumiendo que el ID se asignará en alguna otra parte o por el backend
puntoDeRecogida: this.puntoDeRecogida, puntoDeRecogida: this.puntoDeRecogida,
puntoDeEntrega: this.puntoDeEntrega puntoDeEntrega: this.puntoDeEntrega
}; };
console.log('Nuevo pedido:', nuevoPedido);
this.pedidoService.agregarPedido(nuevoPedido); this.pedidoService.agregarPedido(nuevoPedido);
this.resetearSeleccion(); // Resetear selección tras confirmar el pedido // Cerrar el diálogo y pasar los datos necesarios al componente que abrió el diálogo
this.dialogRef.close({
idRecogida: this.puntoDeRecogida.idUnico,
idEntrega: this.puntoDeEntrega.idUnico
});
} }
else {
console.log('No se ha completado la selección de puntos, no se puede confirmar.');
} }
}
} }
...@@ -19,6 +19,7 @@ export class EstadoPedidoComponent implements OnInit { ...@@ -19,6 +19,7 @@ export class EstadoPedidoComponent implements OnInit {
puntoDeRecogida: string = ''; puntoDeRecogida: string = '';
puntoDeEntrega: string = ''; puntoDeEntrega: string = '';
constructor(private pedidoService: ServicioPedidoService) { } constructor(private pedidoService: ServicioPedidoService) { }
/** /**
......
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { MapaComponent } from './mapa/mapa.component';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
...@@ -17,6 +18,7 @@ export class MapaService { ...@@ -17,6 +18,7 @@ export class MapaService {
constructor() { constructor() {
this.idAMapaImagen = this.creaDeIdAMapa(); this.idAMapaImagen = this.creaDeIdAMapa();
} }
/** /**
...@@ -76,16 +78,9 @@ export class MapaService { ...@@ -76,16 +78,9 @@ export class MapaService {
return mapMatrix; return mapMatrix;
} }
public getMapMatrix(): { id: string, idUnico: number }[][] {
// Método para obtener la celda por su id único return this.mapMatrix;
public getCeldaIdUnico(idUnico: number): { id: string, idUnico: number } | undefined {
for (let row of this.mapMatrix) {
const celdaEncontrada = row.find(cell => cell.idUnico === idUnico);
if (celdaEncontrada) {
return celdaEncontrada;
}
}
return undefined; // Retorna undefined si no encuentra la celda
} }
} }
...@@ -24,7 +24,8 @@ export class MapaComponent implements OnInit { ...@@ -24,7 +24,8 @@ export class MapaComponent implements OnInit {
@Output() celdaSeleccionada = new EventEmitter<{ id: string, idUnico: number, row: number, col: number }>(); @Output() celdaSeleccionada = new EventEmitter<{ id: string, idUnico: number, row: number, col: number }>();
@Output() celdaInvalidaClickeada = new EventEmitter<void>(); @Output() celdaInvalidaClickeada = new EventEmitter<void>();
mapMatrix: {id: string, idUnico: number}[][] = []; mapMatrix: {id: string, idUnico: number}[][] = [];
mapStr: string = ""; // Cadena de texto que representa las casillas del mapa //0202000105030705000200041109060110031000000200080101100110000106010701
@Input() mapStr: string = "0202000105030705000200041109060110031000000200080101100110000106010701"; // Cadena de texto que representa las casillas del mapa
rows: number = 7; rows: number = 7;
cols: number = 5; cols: number = 5;
SeleccionadoIdRecogida: string | null = null; SeleccionadoIdRecogida: string | null = null;
...@@ -71,7 +72,6 @@ export class MapaComponent implements OnInit { ...@@ -71,7 +72,6 @@ export class MapaComponent implements OnInit {
*/ */
ngOnInit(): void { ngOnInit(): void {
this.mapMatrix = this.MapaService.creaMapaMatriz(this.mapStr, this.rows, this.cols); this.mapMatrix = this.MapaService.creaMapaMatriz(this.mapStr, this.rows, this.cols);
//this.cargarMapa();
} }
...@@ -126,5 +126,6 @@ export class MapaComponent implements OnInit { ...@@ -126,5 +126,6 @@ export class MapaComponent implements OnInit {
return; return;
} }
} }
} }
...@@ -12,6 +12,7 @@ export interface Punto { ...@@ -12,6 +12,7 @@ export interface Punto {
id: string; id: string;
row: number; row: number;
col: number; col: number;
idUnico: number;
} }
/** /**
......
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { Pedido } from './pedido.model'; import { Pedido } from './pedido.model';
import { MatSnackBar } from '@angular/material/snack-bar'; // Importa MatSnackBar
@Injectable({ @Injectable({
...@@ -15,7 +16,7 @@ export class ServicioPedidoService { ...@@ -15,7 +16,7 @@ export class ServicioPedidoService {
pedidos$ = this.pedidosSubject.asObservable(); // Un observable público para suscribirse a los cambios de la cola de pedidos. pedidos$ = this.pedidosSubject.asObservable(); // Un observable público para suscribirse a los cambios de la cola de pedidos.
private ultimoId = 0; // Un contador privado para generar IDs únicos para los nuevos pedidos. private ultimoId = 0; // Un contador privado para generar IDs únicos para los nuevos pedidos.
constructor() { } constructor(private snackBar: MatSnackBar) { }
/** /**
* @brief Agrega un nuevo pedido a la cola y emite el cambio a todos los suscriptores. * @brief Agrega un nuevo pedido a la cola y emite el cambio a todos los suscriptores.
...@@ -42,6 +43,8 @@ export class ServicioPedidoService { ...@@ -42,6 +43,8 @@ export class ServicioPedidoService {
const pedidosActuales = this.pedidosSubject.value; const pedidosActuales = this.pedidosSubject.value;
const pedidosActualizados = pedidosActuales.filter(pedido => pedido.id !== id); const pedidosActualizados = pedidosActuales.filter(pedido => pedido.id !== id);
this.pedidosSubject.next(pedidosActualizados); this.pedidosSubject.next(pedidosActualizados);
this.mostrarNotificacion(`Pedido 1 ha finalizado.`);
} }
/** /**
...@@ -53,6 +56,7 @@ export class ServicioPedidoService { ...@@ -53,6 +56,7 @@ export class ServicioPedidoService {
const pedidosActuales = this.pedidosSubject.value; const pedidosActuales = this.pedidosSubject.value;
return pedidosActuales.length > 0 ? pedidosActuales[0] : null; // Retorna el primer pedido de la cola return pedidosActuales.length > 0 ? pedidosActuales[0] : null; // Retorna el primer pedido de la cola
} }
**/
/** /**
* @brief Finaliza el pedido que está actualmente en curso. * @brief Finaliza el pedido que está actualmente en curso.
...@@ -61,14 +65,26 @@ export class ServicioPedidoService { ...@@ -61,14 +65,26 @@ export class ServicioPedidoService {
* que es el que se considera en curso. Si la cola de pedidos está vacía, * que es el que se considera en curso. Si la cola de pedidos está vacía,
* no realiza ninguna acción. * no realiza ninguna acción.
* *
**/
finalizarPedidoEnCurso(): void { finalizarPedidoEnCurso(): void {
const pedidosActuales = this.pedidosSubject.value; const pedidosActuales = this.pedidosSubject.value;
if (pedidosActuales.length > 0) { if (pedidosActuales.length > 0) {
pedidosActuales.shift(); // Elimina el primer elemento de la cola const pedidoFinalizado = pedidosActuales.shift();
// Asegurarse de que pedidoFinalizado no sea undefined antes de usarlo
if (pedidoFinalizado) {
this.pedidosSubject.next([...pedidosActuales]); this.pedidosSubject.next([...pedidosActuales]);
this.mostrarNotificacion(`Pedido ${pedidoFinalizado.id} ha finalizado.`);
} }
} }
*/ }
private mostrarNotificacion(mensaje: string): void {
this.snackBar.open(mensaje, 'OK', {
duration: 10000,
horizontalPosition: 'center',
verticalPosition: 'top',
});
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment