# TP3 : Pupitre de commande et dashboard ## NodeRed ```shell docker run --detach --name nodered ^ --network tp_net ^ -p "1880:1880" ^ -v nodered:/data ^ -e "TZ=Europe/Paris" ^ nodered/node-red:4.1 ``` Node-RED est un outil de développement visuel, basé sur des flux (flows), qui permet de créer facilement des applications connectées en assemblant des blocs logiques. Il fonctionne dans un navigateur et utilise un système de “nœuds” que l’on relie entre eux pour traiter des données, piloter des équipements ou créer des interfaces web. Node-RED est particulièrement utilisé pour : - l’IoT (Internet des Objets) - l’automatisation industrielle - la collecte et transformation de données - la communication avec des protocoles industriels (MQTT, Modbus, OPC-UA…) - la création de petits dashboards ou synoptiques ## RabbitMQ RabbitMQ est un serveur de messagerie qui permet à différentes applications de communiquer entre elles en s’échangeant des messages de manière fiable, asynchrone et découplée. Il utilise principalement le protocole AMQP, gère les files d’attente, l’acheminement intelligent des messages, les accusés de réception et la persistance. RabbitMQ est très utilisé pour : - répartir des tâches entre plusieurs services, - connecter des systèmes industriels ou IoT, - absorber des flux importants sans perdre de messages, - assurer une communication robuste entre modules d’une application ```shell docker run --detach --name rabbitmq \ --network proxy_net \ -p "5672:5672" -p "1883:1883" \ -e "PRABBITMQ_DEFAULT_USER=admin" \ -e "RABBITMQ_DEFAULT_PASS=geii2025" \ -e "RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=-rabbitmq_mqtt tcp_listeners [1883]" \ -v rabbitmq_data:/var/lib/rabbitmq \ -l "caddy=rabbitmq.localhost" \ -l "caddy.reverse_proxy={{upstreams 15672}}" \ -l "caddy.tls=internal" \ rabbitmq:4.1.4-management \ sh -c "rabbitmq-plugins enable --offline rabbitmq_mqtt rabbitmq_management && rabbitmq-server" ``` Ajouter la bibliothèque Dashboard2 ## Programme C Ajouter la bibliothèque MQTT ```c #include #include #include #include #include #include #include #include #include #include #include #undef timeout #include "mqtt/async_client.h" #include ``` Déclarer les constantes ```c /* Configuration MQTT */ const std::string ADDRESS = "tcp://rabbitmq:1883"; const std::string CLIENTID = "CppClientTP"; const std::string TOPIC = "geii/ordre/#"; const int QOS = 1; const int CYCLE_MS = 100; ``` Écrire la fonction qui va traiter l'arrivée des messages ```c class callback : public virtual mqtt::callback { public: void message_arrived(mqtt::const_message_ptr msg) override { std::string payload = msg->to_string(); //... Effectuer les actions en conséquences } }; ``` ```c mqtt::async_client client(ADDRESS, CLIENTID); callback cb; client.set_callback(cb); mqtt::connect_options connOpts; connOpts.set_clean_session(true); connOpts.set_user_name("admin"); connOpts.set_password("geii2025"); try { client.connect(connOpts)->wait(); client.start_consuming(); client.subscribe(TOPIC, QOS)->wait(); } catch (const mqtt::exception &exc) { std::cerr << "Erreur MQTT: " << exc.what() << "\n"; return 1; } ``` Dans la fonction ProcessMQTT créer un objet JSON avec les valeurs des différents capteurs. ```c json obj = { {"entree", _digital[IN_FLOW_IN].dvalue}, {"sortie", _digital[IN_FLOW_OUT].dvalue} }; ``` Envoyer le message ```c std::string payload = obj.dump(); auto msg = mqtt::make_message("geii/telemetry", payload); msg->set_qos(1); client->publish(msg); ``` Après la boucle principale déconnecter MQTT. ```c try { client.unsubscribe(TOPIC)->wait(); client.stop_consuming(); client.disconnect()->wait(); } catch(const mqtt::exception &exc){ std::cerr << "Erreur déconnexion MQTT: " << exc.what() << "\n"; } ``` ## Mode manuel Un appui sur un bouton poussoir (*IN_KEYBOARD_4*) met en route la pompe correspondante (*OUT_PUMP_4*). Un nouvel appui arrête la pompe. Lorsque le système passe d'un mode à l'autre (manuel/automatique) toutes les pompes sont mises à l'arrêt instantanément. * Faire le grafcet de ce fonctionnement * Programmer ce fonctionnement