JSON
This commit is contained in:
181
main.cpp
181
main.cpp
@@ -27,15 +27,25 @@
|
||||
#undef timeout
|
||||
#include "mqtt/async_client.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using json = nlohmann::json;
|
||||
|
||||
// Constantes de fonctionnement
|
||||
#define LEVEL_MIN 2
|
||||
#define FLOW_PER_PUMP 150
|
||||
|
||||
/* 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;
|
||||
|
||||
WINDOW *window;
|
||||
|
||||
int etape = 10; // Étape du grafcet : début Automatique
|
||||
int etape = 0; // Étape du grafcet : début Automatique
|
||||
int bp_mode, bp_mode_fm;
|
||||
unsigned short pompe1, pompe2, pompe3, pompe4; // bouton des pompes 0 (arrêt) / 1 (marche)
|
||||
unsigned short pompe1_old, pompe2_old, pompe3_old, pompe4_old;
|
||||
@@ -74,8 +84,161 @@ Histogram::BucketBoundaries buckets = {
|
||||
Histogram *tank_histogram = nullptr;
|
||||
// ************************************************************
|
||||
|
||||
|
||||
/* Queue thread-safe */
|
||||
std::queue<std::string> orders_queue;
|
||||
std::mutex queue_mtx;
|
||||
|
||||
std::string pop_all_and_get_last() {
|
||||
std::lock_guard<std::mutex> lock(queue_mtx);
|
||||
if (orders_queue.empty()) return "";
|
||||
std::string last;
|
||||
while (!orders_queue.empty()) {
|
||||
last = orders_queue.front();
|
||||
orders_queue.pop();
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
void push_order(const std::string &msg) {
|
||||
std::lock_guard<std::mutex> lock(queue_mtx);
|
||||
orders_queue.push(msg);
|
||||
}
|
||||
|
||||
/* Etats machine */
|
||||
enum class MachineState { STOPPED, RUNNING, ESTOP };
|
||||
std::atomic<MachineState> machine_state(MachineState::STOPPED);
|
||||
std::atomic<bool> estop_flag(false);
|
||||
std::atomic<bool> running(true);
|
||||
|
||||
/* Fonctions d'application */
|
||||
void apply_start() {
|
||||
if(machine_state!=MachineState::RUNNING){
|
||||
std::cout << "[MACHINE] -> START\n";
|
||||
machine_state = MachineState::RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
void apply_stop() {
|
||||
if(machine_state!=MachineState::STOPPED){
|
||||
std::cout << "[MACHINE] -> STOP\n";
|
||||
machine_state = MachineState::STOPPED;
|
||||
}
|
||||
}
|
||||
|
||||
void apply_estop() {
|
||||
if(machine_state!=MachineState::ESTOP){
|
||||
std::cout << "[MACHINE] -> E-STOP\n";
|
||||
machine_state = MachineState::ESTOP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Thread machine */
|
||||
void machine_thread_fn() {
|
||||
while(running) {
|
||||
if(estop_flag) {
|
||||
apply_estop();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MS));
|
||||
continue;
|
||||
}
|
||||
pompe1 = 1;
|
||||
std::string last = pop_all_and_get_last();
|
||||
if(!last.empty()) {
|
||||
if(last=="START") apply_start();
|
||||
if(last=="P1") {
|
||||
pompe1 = 1;
|
||||
} else if(last=="P2") {
|
||||
pompe2 = 1;
|
||||
} else if(last=="P3") {
|
||||
pompe3 = 1;
|
||||
} else if(last=="P4") {
|
||||
pompe4 = 1;
|
||||
}
|
||||
else if(last=="STOP") apply_stop();
|
||||
else std::cout << "[MACHINE] Commande inconnue: '" << last << "'\n";
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MS));
|
||||
}
|
||||
apply_stop();
|
||||
}
|
||||
|
||||
/* Callback MQTT */
|
||||
class callback : public virtual mqtt::callback {
|
||||
public:
|
||||
void message_arrived(mqtt::const_message_ptr msg) override {
|
||||
std::string payload = msg->to_string();
|
||||
if(payload == "E_STOP") {
|
||||
estop_flag = true;
|
||||
std::cout << "[MQTT] E-STOP reçu\n";
|
||||
} else if(payload == "P1") {
|
||||
pompe2 = 1;
|
||||
} else {
|
||||
push_order(payload);
|
||||
std::cout << "[MQTT] Reçu: '" << payload << "'\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SIGINT handler */
|
||||
void sigint_handler(int) {
|
||||
std::cout << "[MAIN] SIGINT reçu\n";
|
||||
running = false;
|
||||
}
|
||||
|
||||
void send_to_influx(double value) {
|
||||
CURL* curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
std::cerr << "Erreur CURL\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Line protocol
|
||||
std::string line = "machine_cycle,machine=convoyeur1 value=" + std::to_string(value);
|
||||
|
||||
// Endpoint InfluxDB 2.x
|
||||
std::string url =
|
||||
"http://influxdb:8086/api/v2/write?org=geii&bucket=mesures&precision=s";
|
||||
|
||||
struct curl_slist* headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Authorization: Token MON_TOKEN");
|
||||
headers = curl_slist_append(headers, "Content-Type: text/plain");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, line.c_str());
|
||||
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
std::cerr << "Erreur CURL: " << curl_easy_strerror(res) << "\n";
|
||||
}
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
|
||||
/* MQTT async client */
|
||||
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("ChangeMe");
|
||||
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;
|
||||
}
|
||||
|
||||
/* Initialisation */
|
||||
ConsoleInit();
|
||||
AffichageWindow();
|
||||
@@ -873,11 +1036,17 @@ void InitPrometheus()
|
||||
|
||||
void ProcessMQTT(mqtt::async_client* client)
|
||||
{
|
||||
std::string payload = R"({
|
||||
"order": "STATUS",
|
||||
"speed": 120,
|
||||
"temperature": 36.1
|
||||
})";
|
||||
json obj = {
|
||||
{"entree", _digital[IN_FLOW_IN].dvalue},
|
||||
{"sortie", _digital[IN_FLOW_OUT].dvalue},
|
||||
{"p1", _digital[IN_FLOW_1].dvalue},
|
||||
{"p2", _digital[IN_FLOW_2].dvalue},
|
||||
{"p3", _digital[IN_FLOW_3].dvalue},
|
||||
{"p4", _digital[IN_FLOW_4].dvalue},
|
||||
{"level", _digital[IN_TANK_LEVEL].dvalue}
|
||||
};
|
||||
|
||||
std::string payload = obj.dump();
|
||||
|
||||
auto msg = mqtt::make_message("geii/telemetry", payload);
|
||||
msg->set_qos(1);
|
||||
|
||||
Reference in New Issue
Block a user