2. Manteniment de màquines

En una planta de fabricació, les màquines generen peticions de manteniment. Hi ha dos tipus de tasques: Avaries Crítiques (Prioritat 1, s’han de reparar immediatament) i Manteniment Preventiu (Prioritat 2, prioritat normal).

Disposes de la classe TascaManteniment que representa una tasca de manteniment. Com a atributs té la prioritat, l’ID de la màquina i el temps estimat de reparació. Només es té en compte la prioritat a l’hora d’ordenar objectes d’aquesta classe.

from dataclasses import dataclass, field

@dataclass(order=True)
class TascaManteniment:
    """Representa una ordre de manteniment amb prioritat."""
    prioritat: int  # 1 per a Crítica (Alta), 2 per a Preventiva (Normal)
    id_maquina: int = field(compare=False)
    temps_reparacio: float = field(compare=False)

Volem simular un patró productor-consumidor usant una cua asíncrona amb prioritat. Dissenya les corutines següents i desa-les al mòdul manteniment (fitxer manteniment.py):

async manteniment.tecnic_manteniment(id_tecnic: int, cua: asyncio.PriorityQueue)

Corutina consumidora que simula un tècnic reparant màquines:

  • Obté una tasca de la cua.

  • Simula la reparació amb un retard (asyncio.sleep()).

  • Informa la cua que la tasca ha finalitzat.

  • Repeteix aquest procés.

Tests

La teva solució ha de passar els tests de test_tecnic_manteniment.py.


async manteniment.monitor_sistema(cua: asyncio.PriorityQueue, total_tasques: int)

Corutina productora que genera peticions de manteniment de manera aleatòria:

  • Genera total_tasques de manteniment.

  • Cada tasca té una prioritat aleatòria (1 o 2) i un temps de reparació entre 0.5 i 1.5 segons.

  • Posa cada tasca a la cua.

Tests

La teva solució ha de passar els tests de test_monitor_sistema.py.


async manteniment.main()

Corutina principal:

  • Crea una cua amb prioritat de mida màxima 5.

  • Crea tres tasques consumidores tecnic_manteniment().

  • Espera que acabi la corutina productora monitor_sistema() després de produir 15 tasques de manteniment.

  • Fa un tancament net tot esperant que les tasques de la cua s’hagin processat i cancel·lant les tasques consumidores.

Per provar-la, afegeix un programa principal al final del mòdul manteniment:

if __name__ == "__main__":
    asyncio.run(main())

Afegeix al lloc adient de la corutina tecnic_manteniment() els missatges

            print(f"[Tècnic {id_tecnic}] Iniciant reparació {tipus} a màquina {tasca.id_maquina}...")
            print(f"[Tècnic {id_tecnic}] Reparació màquina {tasca.id_maquina} finalitzada.")

i a monitor_sistema()

        print(f"[Monitor] Generada tasca {tasca}. Esperant per encuar...")
        print(f"[Monitor] Tasca {tasca.id_maquina} posada a la cua. Mida actual: {cua.qsize()}")

per tal de comprovar que:

  • Hi ha tres consumidors.

  • La cua té un límit de 5 tasques.

  • Es generen 15 tasques de manteniment.

  • Es processen abans les més prioritàries que hi ha a la cua.

  • Acaben totes les tasques de manera neta.

Per exemple:

$ python3 manteniment.py
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=0, temps_reparacio=0.7401123808053198). Esperant per encuar...
[Monitor] Tasca 0 posada a la cua. Mida actual: 1
[Monitor] Generada tasca TascaManteniment(prioritat=2, id_maquina=1, temps_reparacio=0.7882965668444621). Esperant per encuar...
[Monitor] Tasca 1 posada a la cua. Mida actual: 2
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=2, temps_reparacio=0.8390206217312279). Esperant per encuar...
[Monitor] Tasca 2 posada a la cua. Mida actual: 3
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=3, temps_reparacio=0.2481649245147986). Esperant per encuar...
[Monitor] Tasca 3 posada a la cua. Mida actual: 4
[Monitor] Generada tasca TascaManteniment(prioritat=2, id_maquina=4, temps_reparacio=0.10067649290167908). Esperant per encuar...
[Monitor] Tasca 4 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=5, temps_reparacio=0.8786214251964919). Esperant per encuar...
[Tècnic 0] Iniciant reparació CRÍTICA a màquina 0...
[Tècnic 1] Iniciant reparació CRÍTICA a màquina 2...
[Tècnic 2] Iniciant reparació CRÍTICA a màquina 3...
[Monitor] Tasca 5 posada a la cua. Mida actual: 3
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=6, temps_reparacio=0.31093669141678615). Esperant per encuar...
[Monitor] Tasca 6 posada a la cua. Mida actual: 4
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=7, temps_reparacio=1.3847989892890162). Esperant per encuar...
[Monitor] Tasca 7 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=2, id_maquina=8, temps_reparacio=1.146511336599091). Esperant per encuar...
[Tècnic 2] Reparació màquina 3 finalitzada.
[Tècnic 2] Iniciant reparació CRÍTICA a màquina 5...
[Monitor] Tasca 8 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=9, temps_reparacio=0.675109584347738). Esperant per encuar...
[Tècnic 0] Reparació màquina 0 finalitzada.
[Tècnic 0] Iniciant reparació CRÍTICA a màquina 6...
[Monitor] Tasca 9 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=10, temps_reparacio=0.958698645550528). Esperant per encuar...
[Tècnic 1] Reparació màquina 2 finalitzada.
[Tècnic 1] Iniciant reparació CRÍTICA a màquina 7...
[Monitor] Tasca 10 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=2, id_maquina=11, temps_reparacio=1.2133616660820457). Esperant per encuar...
[Tècnic 0] Reparació màquina 6 finalitzada.
[Tècnic 0] Iniciant reparació CRÍTICA a màquina 9...
[Monitor] Tasca 11 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=2, id_maquina=12, temps_reparacio=0.5935960064285833). Esperant per encuar...
[Tècnic 2] Reparació màquina 5 finalitzada.
[Tècnic 2] Iniciant reparació CRÍTICA a màquina 10...
[Monitor] Tasca 12 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=13, temps_reparacio=0.10835887817984446). Esperant per encuar...
[Tècnic 0] Reparació màquina 9 finalitzada.
[Tècnic 0] Iniciant reparació PREVENTIVA a màquina 1...
[Monitor] Tasca 13 posada a la cua. Mida actual: 5
[Monitor] Generada tasca TascaManteniment(prioritat=1, id_maquina=14, temps_reparacio=0.7571606084754389). Esperant per encuar...
[Tècnic 2] Reparació màquina 10 finalitzada.
[Tècnic 2] Iniciant reparació CRÍTICA a màquina 13...
[Monitor] Tasca 14 posada a la cua. Mida actual: 5
[Tècnic 2] Reparació màquina 13 finalitzada.
[Tècnic 2] Iniciant reparació CRÍTICA a màquina 14...
[Tècnic 1] Reparació màquina 7 finalitzada.
[Tècnic 1] Iniciant reparació PREVENTIVA a màquina 4...
[Tècnic 1] Reparació màquina 4 finalitzada.
[Tècnic 1] Iniciant reparació PREVENTIVA a màquina 11...
[Tècnic 0] Reparació màquina 1 finalitzada.
[Tècnic 0] Iniciant reparació PREVENTIVA a màquina 12...
[Tècnic 2] Reparació màquina 14 finalitzada.
[Tècnic 2] Iniciant reparació PREVENTIVA a màquina 8...
[Tècnic 0] Reparació màquina 12 finalitzada.
[Tècnic 1] Reparació màquina 11 finalitzada.
[Tècnic 2] Reparació màquina 8 finalitzada.