diff --git a/.devcontainer/nodered/flows.json b/.devcontainer/nodered/flows.json index 811909c..fcfce2e 100644 --- a/.devcontainer/nodered/flows.json +++ b/.devcontainer/nodered/flows.json @@ -14,7 +14,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B0", - "order": 3, + "order": 1, "width": 0, "height": 0, "emulateClick": false, @@ -53,7 +53,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B1", - "order": 4, + "order": 2, "width": 0, "height": 0, "emulateClick": false, @@ -92,7 +92,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B2", - "order": 5, + "order": 3, "width": 0, "height": 0, "emulateClick": false, @@ -131,7 +131,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B3", - "order": 6, + "order": 4, "width": 0, "height": 0, "emulateClick": false, @@ -177,7 +177,7 @@ "correl": "", "expiry": "", "broker": "5bf949eb0a1b50a7", - "x": 1930, + "x": 1810, "y": 100, "wires": [] }, @@ -185,7 +185,7 @@ "id": "d12767fc3e33bb20", "type": "ui-button", "z": "41526b8c80d5a5f7", - "group": "5fe915fcd26e78ae", + "group": "02fab8cbf37e2bb7", "name": "", "label": "MARCHE", "order": 1, @@ -202,7 +202,7 @@ "payloadType": "str", "topic": "topic", "topicType": "msg", - "buttonColor": "", + "buttonColor": "green", "textColor": "", "iconColor": "", "enableClick": true, @@ -213,33 +213,13 @@ "pointerupPayload": "", "pointerupPayloadType": "str", "x": 700, - "y": 500, + "y": 560, "wires": [ [ "3e0c75aae8971dca" ] ] }, - { - "id": "0ca8f4a10a6048af", - "type": "function", - "z": "41526b8c80d5a5f7", - "name": "format mqtt", - "func": "let marche = Number(flow.get(\"marche\") || 0);\nlet arret = Number(flow.get(\"arret\") || 0);\nlet b0 = Number(flow.get(\"b0\") || 0);\nlet b1 = Number(flow.get(\"b1\") || 0);\nlet b2 = Number(flow.get(\"b2\") || 0);\nlet b3 = Number(flow.get(\"b3\") || 0);\nlet b4 = Number(flow.get(\"b4\") || 0);\nlet b5 = Number(flow.get(\"b5\") || 0);\nlet b6 = Number(flow.get(\"b6\") || 0);\nlet b7 = Number(flow.get(\"b7\") || 0);\n\nmsg.payload = {\n \"marche\": marche,\n \"arret\": arret,\n \"b0\": b0,\n \"b1\": b1,\n \"b2\": b2,\n \"b3\": b3,\n \"b4\": b4,\n \"b5\": b5,\n \"b6\": b6,\n \"b7\": b7\n};\n\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 510, - "y": 40, - "wires": [ - [ - "04e097a5c78127cb" - ] - ] - }, { "id": "a49263451d77f972", "type": "inject", @@ -279,7 +259,7 @@ "finalize": "", "libs": [], "x": 870, - "y": 500, + "y": 560, "wires": [ [ "bf55b8bf4a7aaf10" @@ -471,7 +451,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s0", - "func": "msg.payload = Number(flow.get(\"s0\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s0) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -491,7 +471,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s1", - "func": "msg.payload = Number(flow.get(\"s1\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s1) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -511,7 +491,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s2", - "func": "msg.payload = Number(flow.get(\"s2\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s2) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -651,7 +631,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s3", - "func": "msg.payload = Number(flow.get(\"s3\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s3) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -671,7 +651,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s4", - "func": "msg.payload = Number(flow.get(\"s4\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s4) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -691,7 +671,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s5", - "func": "msg.payload = Number(flow.get(\"s5\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s5) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -711,7 +691,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s6", - "func": "msg.payload = Number(flow.get(\"s6\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s6) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -731,7 +711,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "s7", - "func": "msg.payload = Number(flow.get(\"s7\")) ? \"🟩\" : \"🟥\";\n\nreturn msg;", + "func": "msg.payload = Number(msg.payload.s7) ? \"🟩\" : \"🟥\";\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -751,18 +731,18 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "reset", - "func": "flow.set(\"marche\", 1);\n\nflow.set(\"b0\", 0);\nflow.set(\"b1\", 0);\nflow.set(\"b2\", 0);\nflow.set(\"b3\", 0);\nflow.set(\"b4\", 0);\nflow.set(\"b5\", 0);\nflow.set(\"b6\", 0);\nflow.set(\"b7\", 0);\n\nflow.set(\"s0\", 0);\nflow.set(\"s1\", 0);\nflow.set(\"s2\", 0);\nflow.set(\"s3\", 0);\nflow.set(\"s4\", 0);\nflow.set(\"s5\", 0);\nflow.set(\"s6\", 0);\nflow.set(\"s7\", 0);\n\nreturn msg;", + "func": "flow.set(\"i0\", 0);\nflow.set(\"i1\", 0);\nflow.set(\"i2\", 0);\nflow.set(\"i3\", 0);\nflow.set(\"i4\", 0);\nflow.set(\"i5\", 0);\nflow.set(\"i6\", 0);\nflow.set(\"i7\", 0);\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 310, + "x": 850, "y": 40, "wires": [ [ - "0ca8f4a10a6048af" + "bf55b8bf4a7aaf10" ] ] }, @@ -773,7 +753,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B4", - "order": 7, + "order": 5, "width": 0, "height": 0, "emulateClick": false, @@ -812,7 +792,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B5", - "order": 8, + "order": 6, "width": 0, "height": 0, "emulateClick": false, @@ -851,7 +831,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B6", - "order": 9, + "order": 7, "width": 0, "height": 0, "emulateClick": false, @@ -890,7 +870,7 @@ "group": "5fe915fcd26e78ae", "name": "", "label": "B7", - "order": 10, + "order": 8, "width": 0, "height": 0, "emulateClick": false, @@ -1040,7 +1020,7 @@ "id": "d64b5ceb51e6356d", "type": "ui-button", "z": "41526b8c80d5a5f7", - "group": "5fe915fcd26e78ae", + "group": "02fab8cbf37e2bb7", "name": "", "label": "ARRET", "order": 2, @@ -1057,7 +1037,7 @@ "payloadType": "str", "topic": "topic", "topicType": "msg", - "buttonColor": "", + "buttonColor": "red", "textColor": "", "iconColor": "", "enableClick": true, @@ -1068,7 +1048,7 @@ "pointerupPayload": "", "pointerupPayloadType": "str", "x": 700, - "y": 540, + "y": 600, "wires": [ [ "6144c03f7e61ad75" @@ -1100,7 +1080,7 @@ "type": "function", "z": "41526b8c80d5a5f7", "name": "format mqtt", - "func": "let i0 = Number(flow.get(\"i0\") || 0);\nlet i1 = Number(flow.get(\"i1\") || 0);\nlet i2 = Number(flow.get(\"i2\") || 0);\nlet i3 = Number(flow.get(\"i3\") || 0);\nlet i4 = Number(flow.get(\"i4\") || 0);\nlet i5 = Number(flow.get(\"i5\") || 0);\nlet i6 = Number(flow.get(\"i6\") || 0);\nlet i7 = Number(flow.get(\"i7\") || 0);\n\nif (typeof msg.payload[\"arret\"] === 'undefined') msg.payload[\"arret\"] = 1;\nif (typeof msg.payload[\"marche\"] === 'undefined') msg.payload[\"marche\"] = 0;\n\nif (typeof msg.payload[\"b0\"] === 'undefined') msg.payload[\"b0\"] = 0;\nif (typeof msg.payload[\"b1\"] === 'undefined') msg.payload[\"b1\"] = 0;\nif (typeof msg.payload[\"b2\"] === 'undefined') msg.payload[\"b2\"] = 0;\nif (typeof msg.payload[\"b3\"] === 'undefined') msg.payload[\"b3\"] = 0;\nif (typeof msg.payload[\"b4\"] === 'undefined') msg.payload[\"b4\"] = 0;\nif (typeof msg.payload[\"b5\"] === 'undefined') msg.payload[\"b5\"] = 0;\nif (typeof msg.payload[\"b6\"] === 'undefined') msg.payload[\"b6\"] = 0;\nif (typeof msg.payload[\"b7\"] === 'undefined') msg.payload[\"b7\"] = 0;\n\nmsg.payload[\"i0\"] = i0;\nmsg.payload[\"i1\"] = i1;\nmsg.payload[\"i2\"] = i2;\nmsg.payload[\"i3\"] = i3;\nmsg.payload[\"i4\"] = i4;\nmsg.payload[\"i5\"] = i5;\nmsg.payload[\"i6\"] = i6;\nmsg.payload[\"i7\"] = i7;\n\nreturn msg;", + "func": "let i0 = Number(flow.get(\"i0\")) || 0;\nlet i1 = Number(flow.get(\"i1\")) || 0;\nlet i2 = Number(flow.get(\"i2\")) || 0;\nlet i3 = Number(flow.get(\"i3\")) || 0;\nlet i4 = Number(flow.get(\"i4\")) || 0;\nlet i5 = Number(flow.get(\"i5\")) || 0;\nlet i6 = Number(flow.get(\"i6\")) || 0;\nlet i7 = Number(flow.get(\"i7\")) || 0;\n\nif (typeof msg.payload[\"arret\"] === 'undefined') msg.payload[\"arret\"] = 1;\nif (typeof msg.payload[\"marche\"] === 'undefined') msg.payload[\"marche\"] = 0;\n\nif (typeof msg.payload[\"b0\"] === 'undefined') msg.payload[\"b0\"] = 0;\nif (typeof msg.payload[\"b1\"] === 'undefined') msg.payload[\"b1\"] = 0;\nif (typeof msg.payload[\"b2\"] === 'undefined') msg.payload[\"b2\"] = 0;\nif (typeof msg.payload[\"b3\"] === 'undefined') msg.payload[\"b3\"] = 0;\nif (typeof msg.payload[\"b4\"] === 'undefined') msg.payload[\"b4\"] = 0;\nif (typeof msg.payload[\"b5\"] === 'undefined') msg.payload[\"b5\"] = 0;\nif (typeof msg.payload[\"b6\"] === 'undefined') msg.payload[\"b6\"] = 0;\nif (typeof msg.payload[\"b7\"] === 'undefined') msg.payload[\"b7\"] = 0;\n\nmsg.payload[\"i0\"] = i0;\nmsg.payload[\"i1\"] = i1;\nmsg.payload[\"i2\"] = i2;\nmsg.payload[\"i3\"] = i3;\nmsg.payload[\"i4\"] = i4;\nmsg.payload[\"i5\"] = i5;\nmsg.payload[\"i6\"] = i6;\nmsg.payload[\"i7\"] = i7;\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -1140,7 +1120,7 @@ "id": "057f5330eb0243b5", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i1", "func": "flow.set(\"i1\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1194,7 +1174,7 @@ "id": "ed8a7b695f241e17", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i2", "func": "flow.set(\"i2\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1248,7 +1228,7 @@ "id": "f7196bb1c9ad7882", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i3", "func": "flow.set(\"i3\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1302,7 +1282,7 @@ "id": "a14b6f743fc24f5a", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i4", "func": "flow.set(\"i4\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1356,7 +1336,7 @@ "id": "3a78dbb26cfb4ced", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i5", "func": "flow.set(\"i5\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1410,7 +1390,7 @@ "id": "0da4875391d23ba7", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i6", "func": "flow.set(\"i6\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1464,7 +1444,7 @@ "id": "6343064ecf3d8a64", "type": "function", "z": "41526b8c80d5a5f7", - "name": "set i0", + "name": "set i7", "func": "flow.set(\"i7\", msg.payload);\nmsg.payload = {};\nreturn msg;", "outputs": 1, "timeout": 0, @@ -1578,7 +1558,7 @@ "finalize": "", "libs": [], "x": 860, - "y": 540, + "y": 600, "wires": [ [ "bf55b8bf4a7aaf10" @@ -1602,22 +1582,71 @@ "topic": "", "payload": "{\"t\":0}", "payloadType": "json", - "x": 1140, - "y": 140, + "x": 1220, + "y": 240, "wires": [ [ "bf55b8bf4a7aaf10" ] ] }, + { + "id": "5281ea0425c23135", + "type": "ui-slider", + "z": "41526b8c80d5a5f7", + "group": "b1bde11bdd78b9f1", + "name": "", + "label": "Consigne", + "tooltip": "", + "order": 2, + "width": 0, + "height": 0, + "passthru": false, + "outs": "all", + "topic": "topic", + "topicType": "msg", + "thumbLabel": "true", + "showTicks": "always", + "min": 0, + "max": "100", + "step": "1", + "className": "", + "iconPrepend": "", + "iconAppend": "", + "color": "", + "colorTrack": "", + "colorThumb": "", + "showTextField": false, + "x": 880, + "y": 1440, + "wires": [ + [] + ] + }, + { + "id": "8c90e91ac1299743", + "type": "ui-progress", + "z": "41526b8c80d5a5f7", + "group": "b1bde11bdd78b9f1", + "name": "", + "label": "Progress", + "order": 1, + "width": 0, + "height": 0, + "color": "", + "className": "", + "x": 880, + "y": 1500, + "wires": [] + }, { "id": "5fe915fcd26e78ae", "type": "ui-group", - "name": "Pupitre", + "name": "Boutons", "page": "bb436fe040268d40", "width": "2", "height": 1, - "order": 1, + "order": 2, "showTitle": true, "className": "", "visible": "true", @@ -1655,6 +1684,20 @@ "userProps": "", "sessionExpiry": "" }, + { + "id": "02fab8cbf37e2bb7", + "type": "ui-group", + "name": "Alimentation", + "page": "bb436fe040268d40", + "width": "2", + "height": 1, + "order": 1, + "showTitle": true, + "className": "", + "visible": "true", + "disabled": "false", + "groupType": "default" + }, { "id": "c3dd11d0778f9e67", "type": "ui-group", @@ -1662,7 +1705,7 @@ "page": "bb436fe040268d40", "width": "2", "height": 1, - "order": 3, + "order": 4, "showTitle": true, "className": "", "visible": "true", @@ -1676,7 +1719,21 @@ "page": "bb436fe040268d40", "width": "2", "height": 1, - "order": 2, + "order": 3, + "showTitle": true, + "className": "", + "visible": "true", + "disabled": "false", + "groupType": "default" + }, + { + "id": "b1bde11bdd78b9f1", + "type": "ui-group", + "name": "Afficheur", + "page": "bb436fe040268d40", + "width": 6, + "height": 1, + "order": 5, "showTitle": true, "className": "", "visible": "true", @@ -1759,7 +1816,7 @@ } }, { - "id": "42905d93d09af6d5", + "id": "ca70d5f93a31281c", "type": "global-config", "env": [], "modules": { diff --git a/AutomForArduino.cpp b/AutomForArduino.cpp deleted file mode 100644 index ba55da8..0000000 --- a/AutomForArduino.cpp +++ /dev/null @@ -1,394 +0,0 @@ -#include -#include -#include - -#undef timeout -#include "mqtt/async_client.h" - -#include -using json = nlohmann::json; - -/* From Arduino.h */ - -#define HIGH 0x1 -#define LOW 0x00 - -#define IO_INPUT 0x02 -#define IO_OUTPUT 0x04 - -#define DIGITAL 0x08 -#define ANALOG 0x10 - -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 - -#define true 1 -#define false 0 - -// Temps - -// Timestamp unix en millisecondes -// t_start : timestamp de départ -// t_backup : timestamp de la précédente itération -// t_elapsed : temps écoulé en secondes depuis le départ -// dt (delta t) : temps écoulé en secondes depuis la dernière itération -unsigned long t_start, t_backup; -double t_elapsed, dt; - -unsigned long millis() -{ - struct timespec now; - clock_gettime(CLOCK_REALTIME, &now); - return ((unsigned long)now.tv_sec) * 1000 + ((unsigned long)now.tv_nsec) / 1000000; -} - -#define OP_DIGITAL_READ 0 -#define OP_DIGITAL_WRITE 1 -#define OP_ANALOG_READ 2 -#define OP_ANALOG_WRITE 3 -#define OP_PIN_MODE 4 - -int marche = 0; -int arret = 1; -int b0, b1, b2, b3, b4, b5, b6, b7; -int i0, i1, i2, i3, i4, i5, i6, i7; -int s0, s1, s2, s3, s4, s5, s6, s7; - -/* ******************************************************** - * MQTT * - * * - ******************************************************** */ - -/* Configuration MQTT */ -const std::string ADDRESS = "tcp://rabbitmq:1883"; -const std::string CLIENTID = "CppClientTP"; -const std::string TOPIC = "geii/in/#"; -const int QOS = 1; -const int CYCLE_MS = 100; - -mqtt::async_client client(ADDRESS, CLIENTID); - -void mqtt_process(mqtt::async_client* client) -{ - json obj = { - {"s0", s0 }, - {"s1", s1 }, - {"s2", s2 }, - {"s3", s3 }, - {"s4", s4 }, - {"s5", s5 }, - {"s6", s6 }, - {"s7", s7 }, - }; - - std::string payload = obj.dump(); - auto msg = mqtt::make_message("geii/out", payload); - msg->set_qos(1); - client->publish(msg); - - usleep(100000); -} - - -// Réception des messages MQTT -// ************************************************************ -class callback : public virtual mqtt::callback { -public: - void message_arrived(mqtt::const_message_ptr msg) override { - std::string payload = msg->to_string(); - - try { - json j = json::parse(payload); - - marche = 0; arret = 1; - b0 = b1 = b2 = b3 = b4 = b5 = b6 = b7 = 0; - - // Ne rien faire si l'objet JSON est vide - if (j.empty()) return; - - if (j.contains("marche")) marche = j["marche"].get() != 0; - if (j.contains("arret")) arret = j["arret"].get() != 0; - - if (j.contains("b0")) b0 = j["b0"].get() != 0; - if (j.contains("b1")) b1 = j["b1"].get() != 0; - if (j.contains("b2")) b2 = j["b2"].get() != 0; - if (j.contains("b3")) b3 = j["b3"].get() != 0; - if (j.contains("b4")) b4 = j["b4"].get() != 0; - if (j.contains("b5")) b5 = j["b5"].get() != 0; - if (j.contains("b6")) b6 = j["b6"].get() != 0; - if (j.contains("b7")) b7 = j["b7"].get() != 0; - - if (j.contains("i0")) i0 = j["i0"].get() != 0; - if (j.contains("i1")) i1 = j["i1"].get() != 0; - if (j.contains("i2")) i2 = j["i2"].get() != 0; - if (j.contains("i3")) i3 = j["i3"].get() != 0; - if (j.contains("i4")) i4 = j["i4"].get() != 0; - if (j.contains("i5")) i5 = j["i5"].get() != 0; - if (j.contains("i6")) i6 = j["i6"].get() != 0; - if (j.contains("i7")) i7 = j["i7"].get() != 0; - - std::cout << "Pompes : " << marche << " " << arret << " " << b0 << " " << b1 << " " << b2 << " " << b3 << " " << b4 << " " << b5 << " " << b6 << " " << b7 << std::endl; - } - catch (const json::parse_error& e) { - std::cerr << "Erreur JSON : " << e.what() << "\n"; - } - } -}; - -callback cb; - -void mqtt_open(mqtt::async_client* client) { - - 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"; - } - -} - -void mqtt_close() { - try { - client.unsubscribe(TOPIC)->wait(); - client.stop_consuming(); - client.disconnect()->wait(); - } catch(const mqtt::exception &exc){ - std::cerr << "Erreur déconnexion MQTT: " << exc.what() << std::endl; - } -} -// ************************************************************ - - -/* ******************************************************** - * TEMPORISATION RETARD A LA MONTEE * - * La sortie passe à 1 au bout de la tempo * - ******************************************************** */ - -class TemporisationRetardMontee -{ - // methodes - public : - // Contructeur qui prend la duree souhaitee de la temporisation - TemporisationRetardMontee(unsigned long duree) - { - this->duree = duree; - sortie = false; - captureTemps = false; - } - // Activation de la temporisation. Doit etre fait tout le temps de la duree de la tempo - void activation() - { - // Capture du temps de reference - if(!captureTemps) - { - debut = millis(); - captureTemps = true; - } - // Calcul du temps ecoule depuis le temps de reference - tempsEcoule = millis() - debut; - // Mise a 1 de la fin de tempo - if (tempsEcoule >= duree) - { - sortie = true; - captureTemps = false; - } - else - { - sortie = false; - } - } - // Precharge de la temporisation - void setDuree(unsigned long majduree) - { - duree = majduree; - sortie = false; - captureTemps = false; - } - // Interrogation du bit de fin de tempo - bool getSortie() - { - return(sortie); - } - // Recuperation du temps ecoule depuis le debut si necessaire - unsigned long getTempsEcoule() - { - return(tempsEcoule); - } - - // Attributs - private: - unsigned long duree; - unsigned long debut; - unsigned long tempsEcoule; - bool captureTemps; - bool sortie; -}; - -/******************************************************** -* TEMPORISATION RETARD A LA DESCENTE * -* La sortie passe à 0 au bout de la tempo * -*********************************************************/ -class TemporisationRetardDescente -{ - public : - // Contructeur qui prend la duree souhaitee de la temporisation - TemporisationRetardDescente(unsigned long duree) - { - this->duree = duree; - sortie = false; - captureTemps = false; - } - // Activation de la temporisation. Doit etre fait tout le temps de la duree de la tempo - void activation() - { - // Capture du temps de reference - if(!captureTemps) - { - debut = millis(); - captureTemps = true; - sortie = true; - } - // Calcul du temps ecoule depuis le temps de reference - tempsEcoule = millis() - debut; - // Mise a 0 de la fin de tempo - if (tempsEcoule >= duree) - { - sortie = false; - captureTemps = false; - } - } - // Precharge de la temporisation - void setDuree(unsigned long majduree) - { - duree = majduree; - sortie = false; - captureTemps = false; - } - // Interrogration du bit de fin de tempo - bool getSortie() - { - return(sortie); - } - // Recuperation du temps ecoule depuis le debut si necessaire - unsigned long getTempsEcoule() - { - return(tempsEcoule); - } - - private: - unsigned long duree; - unsigned long debut; - unsigned long tempsEcoule; - bool captureTemps; - bool sortie; -}; - -/******************************************************** -**** CLIGNOTEUR ************************************* -*********************************************************/ -class Clignoteur -{ - // methodes - public : - // Construteur qui prend en parametre le temps haut ou bas souhaitee - Clignoteur(int baseDeTemps) - { - this->baseDeTemps = baseDeTemps; - } - // Fonction qui renvoie true si le clignoteur est ├á l'├®tat haut et false s'il est ├á l'├®tat bas - bool statut() - { - return ((millis() / baseDeTemps) % 2 == 1); - } - - // Attributs - private: - int baseDeTemps; -}; - -/******************************************************** -**** COMPTEUR ************************************* -**** ATTENTION : Il faut gerer le front montant dans le programme -*********************************************************/ -class Compteur -{ - // methodes - public : - // Constructeur qui prend en parametre la valeur de preselection - Compteur(int valeurPreselection) - { - this->valeurPreselection = valeurPreselection; - valeur = 0; - } - // Incrementation du compteur - void incrementer() - { - valeur++; - } - // Decrementation du compteur - void decrementer() - { - valeur--; - } - // remise a zero du compteur - void remettreAZero() - { - valeur = 0; - } - // recuperation de la valeur courante - int getValeurCourante() - { - return(valeur); - } - // est-ce que la preselection est atteinte (sortie Q compteur Siemens ou Schnieder) - bool getSortie() - { - return(valeur == valeurPreselection); - } - - // Attributs - private: - int valeur; - int valeurPreselection; -}; - -/******************************************************** -**** MISE A L'ECHELLE DE VALEUR ************************ -*********************************************************/ -class MiseAEchelle -{ - public : - // Constructeur qui ne prend en parametre la plage d'entree et la plage de sortie - MiseAEchelle(float minEntree,float maxEntree,float minSortie,float maxSortie) - { - this->minEntree = minEntree; - this->maxEntree = maxEntree; - this->minSortie = minSortie; - this->maxSortie = maxSortie; - } - // fonction de conversion qui prend la valeur a convertir et renvoie la valeur convertie - float convertir(float valeurAConvertir) - { - if(valeurAConvertir >= minEntree && valeurAConvertir <= maxEntree) - { - float norm = (1 / (maxEntree - minEntree)) * (valeurAConvertir - minEntree); - float scale = (maxSortie - minSortie) * norm + minSortie; - return(scale); - } - return(-1000); - } - - // Attributs - private: - float minEntree; - float minSortie; - float maxEntree; - float maxSortie; -}; diff --git a/autom.cpp b/autom.cpp index a55f5e1..ec5a3bd 100644 --- a/autom.cpp +++ b/autom.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #undef timeout #include "mqtt/async_client.h" @@ -8,8 +8,6 @@ #include using json = nlohmann::json; -#include - /* From Arduino.h */ #define HIGH 0x1 @@ -27,14 +25,6 @@ using json = nlohmann::json; #define true 1 #define false 0 -/* Configuration MQTT */ -const std::string ADDRESS = "tcp://rabbitmq:1883"; -const std::string CLIENTID = "CppClientTP"; -const std::string TOPIC = "geii/in/#"; -const int QOS = 1; - -int s0, s1; - // Temps // Timestamp unix en millisecondes @@ -58,132 +48,124 @@ unsigned long millis() #define OP_ANALOG_WRITE 3 #define OP_PIN_MODE 4 -typedef struct PinIO -{ - unsigned char mode; - int ivalue; - double dvalue; - int error; // % = 1 /error ex 1 / 20 = 5 % - double efficacite; // 0 - 100% - unsigned long start; - unsigned long time; - double duration; - unsigned int nb; // compteur d'activation - int memory; - unsigned char raising; - unsigned char falling; -} PinIO; +int marche = 0; +int arret = 1; +int b0, b1, b2, b3, b4, b5, b6, b7; +int i0, i1, i2, i3, i4, i5, i6, i7; +int s0, s1, s2, s3, s4, s5, s6, s7; -PinIO _digital[256]; +/* ******************************************************** + * MQTT * + * * + ******************************************************** */ -void pinMode(unsigned char p, unsigned char mode) -{ - _digital[p].mode = 0x01 | mode; - - _digital[p].ivalue = 0; - _digital[p].dvalue = 0.0; - - _digital[p].nb = 0; - _digital[p].time = 0.0; - _digital[p].duration = 0.0; - _digital[p].start = 0; - _digital[p].raising = 0; - _digital[p].memory = 0; -} - -// Réception des messages MQTT -// ************************************************************ -class callback : public virtual mqtt::callback -{ -public: - void message_arrived(mqtt::const_message_ptr msg) override - { - std::string payload = msg->to_string(); - - std::cout << "MQTT IN : "; - - try - { - json j = json::parse(payload); - - // Ne rien faire si l'objet JSON est vide - if (j.empty()) - return; - - if (j.contains("b0")) - s0 = j["b0"].get() != 0; - - std::cout << "boutons : " << s0 << std::endl; - } - catch (const json::parse_error &e) - { - std::cerr << "Erreur JSON : " << e.what() << "\n"; - } - } -}; -// ************************************************************ +/* Configuration MQTT */ +const std::string ADDRESS = "tcp://rabbitmq:1883"; +const std::string CLIENTID = "CppClientTP"; +const std::string TOPIC = "geii/in/#"; +const int QOS = 1; +const int CYCLE_MS = 100; mqtt::async_client client(ADDRESS, CLIENTID); -void open() { - - 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; - } -} - -void close() { - try - { - client.unsubscribe(TOPIC)->wait(); - client.stop_consuming(); - client.disconnect()->wait(); - } - catch (const mqtt::exception &exc) - { - std::cerr << "Erreur déconnexion MQTT: " << exc.what() << std::endl; - } - - std::cout << "Fin du programme" << std::endl; -} - -void send() +void mqtt_process(mqtt::async_client* client) { - json obj = { - {"s0", s0}, - {"s1", s1}, - {"s2", 0}, - {"s3", 1}, - {"s4", 1}, - }; + json obj = { + {"s0", s0 }, + {"s1", s1 }, + {"s2", s2 }, + {"s3", s3 }, + {"s4", s4 }, + {"s5", s5 }, + {"s6", s6 }, + {"s7", s7 }, + }; - std::string payload = obj.dump(); - auto msg = mqtt::make_message("geii/out", payload); - msg->set_qos(0); - client.publish(msg); + std::string payload = obj.dump(); + auto msg = mqtt::make_message("geii/out", payload); + msg->set_qos(1); + client->publish(msg); - std::cout << s0 << std::endl; - - usleep(100000); + usleep(100000); } +// Réception des messages MQTT +// ************************************************************ +class callback : public virtual mqtt::callback { +public: + void message_arrived(mqtt::const_message_ptr msg) override { + std::string payload = msg->to_string(); + + try { + json j = json::parse(payload); + + marche = 0; arret = 1; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = b7 = 0; + + // Ne rien faire si l'objet JSON est vide + if (j.empty()) return; + + if (j.contains("marche")) marche = j["marche"].get() != 0; + if (j.contains("arret")) arret = j["arret"].get() != 0; + + if (j.contains("b0")) b0 = j["b0"].get() != 0; + if (j.contains("b1")) b1 = j["b1"].get() != 0; + if (j.contains("b2")) b2 = j["b2"].get() != 0; + if (j.contains("b3")) b3 = j["b3"].get() != 0; + if (j.contains("b4")) b4 = j["b4"].get() != 0; + if (j.contains("b5")) b5 = j["b5"].get() != 0; + if (j.contains("b6")) b6 = j["b6"].get() != 0; + if (j.contains("b7")) b7 = j["b7"].get() != 0; + + if (j.contains("i0")) i0 = j["i0"].get() != 0; + if (j.contains("i1")) i1 = j["i1"].get() != 0; + if (j.contains("i2")) i2 = j["i2"].get() != 0; + if (j.contains("i3")) i3 = j["i3"].get() != 0; + if (j.contains("i4")) i4 = j["i4"].get() != 0; + if (j.contains("i5")) i5 = j["i5"].get() != 0; + if (j.contains("i6")) i6 = j["i6"].get() != 0; + if (j.contains("i7")) i7 = j["i7"].get() != 0; + + std::cout << "Pompes : " << marche << " " << arret << " B " << b0 << " " << b1 << " " << b2 << " " << b3 << " " << b4 << " " << b5 << " " << b6 << " " << b7 << " I " << i0 << " " << i1 << " " << i2 << " " << i3 << " " << i4 << " " << i5 << " " << i6 << " " << i7 << std::endl; + } + catch (const json::parse_error& e) { + std::cerr << "Erreur JSON : " << e.what() << "\n"; + } + } +}; + +callback cb; + +void mqtt_open(mqtt::async_client* client) { + + 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"; + } + +} + +void mqtt_close() { + try { + client.unsubscribe(TOPIC)->wait(); + client.stop_consuming(); + client.disconnect()->wait(); + } catch(const mqtt::exception &exc){ + std::cerr << "Erreur déconnexion MQTT: " << exc.what() << std::endl; + } +} +// ************************************************************ + + /* ******************************************************** * TEMPORISATION RETARD A LA MONTEE * * La sortie passe à 1 au bout de la tempo * @@ -250,7 +232,7 @@ class TemporisationRetardMontee }; /******************************************************** -* TEMPORISATION RETARD A LA DESCENTE * +* TEMPORISATION RETARD A LA DESCENTE * * La sortie passe à 0 au bout de la tempo * *********************************************************/ class TemporisationRetardDescente @@ -410,87 +392,3 @@ class MiseAEchelle float maxEntree; float maxSortie; }; - -/* READ */ - -int digitalRead(int p) -{ - return ((_digital[p].mode & IO_INPUT) && (_digital[p].mode & DIGITAL) && (_digital[p].mode & 0x01)) ? _digital[p].ivalue : 0; -} - -double analogRead(int p) -{ - return ((_digital[p].mode & IO_INPUT) && (_digital[p].mode & ANALOG) && (_digital[p].mode & 0x01)) ? _digital[p].dvalue : 0.0; -} - -/* WRITE */ - -void digitalWrite(unsigned int p, int value) -{ - if (p > 255) - { - printf("Pin %d is out of Range.", p); - return; - } - - // En panne ! - if (!(_digital[p].mode & 0x01)) - { - return; - } - - if (!(_digital[p].mode & IO_OUTPUT && _digital[p].mode & DIGITAL)) - { - printf("Pin %d is not a digital input.", p); - return; - } - - unsigned long m = millis(); - - if (value != _digital[p].ivalue) - { - _digital[p].time = _digital[p].time > 5000 ? 0 : 5000 - _digital[p].time; - } - else - { - _digital[p].time += m - _digital[p].start; - } - - if (value && !_digital[p].ivalue) - { - _digital[p].start = m; - _digital[p].nb += 1; - } - else if (value) - { - _digital[p].duration += dt; - } - - _digital[p].raising = (_digital[p].memory < _digital[p].ivalue); - _digital[p].falling = (_digital[p].memory > _digital[p].ivalue); - _digital[p].memory = _digital[p].ivalue; - _digital[p].ivalue = value; -} - -void analogWrite(unsigned int p, double value) -{ - if (p > 31) - { - printf("Pin %d is out of Range.", p); - return; - } - - // En panne - if (!(_digital[p].mode & 0x01)) - { - return; - } - - if (!(_digital[p].mode & IO_OUTPUT) || !(_digital[p].mode & ANALOG)) - { - printf("Pin %d is not a analog input.", p); - return; - } - - _digital[p].dvalue = value; -} diff --git a/main.cpp b/main.cpp index 9638c40..d81e505 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ #include "main.hpp" -#include "AutomForArduino.cpp" +#include "autom.cpp" int main() { @@ -7,14 +7,6 @@ int main() while (1) { - s0 = i0; - s1 = i1; - s2 = i2; - s3 = i3; - s4 = b4; - s5 = b5; - s6 = b6; - s7 = b7; mqtt_process(&client); }