initial commit
This commit is contained in:
55
.devcontainer/Dockerfile
Normal file
55
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
FROM debian:stable-slim
|
||||||
|
|
||||||
|
ARG USERNAME=vscode
|
||||||
|
ARG USER_UID=1000
|
||||||
|
ARG USER_GID=1000
|
||||||
|
|
||||||
|
RUN groupadd --gid $USER_GID $USERNAME \
|
||||||
|
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
|
||||||
|
&& apt-get update && apt-get install -y sudo \
|
||||||
|
&& echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
RUN RUN set -eux; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y \
|
||||||
|
git \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
gdb;
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y \
|
||||||
|
libncurses-dev \
|
||||||
|
libmicrohttpd-dev \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
prometheus-cpp-dev \
|
||||||
|
nlohmann-json3-dev
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y \
|
||||||
|
libpaho-mqtt-dev
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
git clone https://github.com/eclipse/paho.mqtt.cpp.git; \
|
||||||
|
cd paho.mqtt.cpp; \
|
||||||
|
git submodule init; \
|
||||||
|
git submodule update; \
|
||||||
|
mkdir build && cd build; \
|
||||||
|
cmake -DPAHO_WITH_MQTT_C=ON ..; \
|
||||||
|
cmake --build . --target install; \
|
||||||
|
ldconfig;
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y \
|
||||||
|
librabbitmq4 \
|
||||||
|
librabbitmq-dev;\
|
||||||
|
apt-get clean
|
||||||
|
|
||||||
|
USER $USERNAME
|
||||||
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
CMD ["sleep infinity"]
|
||||||
54
.devcontainer/compose.yml
Normal file
54
.devcontainer/compose.yml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
services:
|
||||||
|
dev:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ..:/workspace:cached
|
||||||
|
command: sleep infinity
|
||||||
|
networks:
|
||||||
|
- dev_net
|
||||||
|
|
||||||
|
nodered:
|
||||||
|
build: ./nodered
|
||||||
|
container_name: nodered
|
||||||
|
ports:
|
||||||
|
- "1880:1880"
|
||||||
|
networks:
|
||||||
|
- dev_net
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Paris
|
||||||
|
volumes:
|
||||||
|
- nodered:/data
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq:4.1.4-management
|
||||||
|
container_name: rabbitmq
|
||||||
|
environment:
|
||||||
|
RABBITMQ_DEFAULT_USER: "admin"
|
||||||
|
RABBITMQ_DEFAULT_PASS: "geii2025"
|
||||||
|
|
||||||
|
# Activation MQTT sur le port 1883
|
||||||
|
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: >
|
||||||
|
-rabbitmq_mqtt tcp_listeners [1883]
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "5672:5672" # AMQP
|
||||||
|
- "1883:1883" # MQTT
|
||||||
|
- "15672:15672" # RabbitMQ Manager
|
||||||
|
networks:
|
||||||
|
- dev_net
|
||||||
|
volumes:
|
||||||
|
- rabbitmq:/var/lib/rabbitmq
|
||||||
|
|
||||||
|
# Activation des plugins + démarrage serveur
|
||||||
|
command: >
|
||||||
|
sh -c "rabbitmq-plugins enable --offline rabbitmq_mqtt rabbitmq_management &&
|
||||||
|
rabbitmq-server"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
dev_net:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nodered:
|
||||||
|
rabbitmq:
|
||||||
22
.devcontainer/devcontainer.json
Normal file
22
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "sarii",
|
||||||
|
"dockerComposeFile": [
|
||||||
|
"compose.yml"
|
||||||
|
],
|
||||||
|
"service": "dev",
|
||||||
|
"workspaceFolder": "/workspace",
|
||||||
|
"postStartCommand": "cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
"remote.downloadExtensionsLocally": true,
|
||||||
|
"telemetry.enableTelemetry": false,
|
||||||
|
"extensions.ignoreRecommendations": true,
|
||||||
|
"workbench.remoteIndicator.showExtensionRecommendations": false
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"ms-vscode.cpptools"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
.devcontainer/nodered/Dockerfile
Normal file
7
.devcontainer/nodered/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM nodered/node-red:4.1
|
||||||
|
|
||||||
|
# Installer FlowFuse Dashboard
|
||||||
|
RUN npm install --unsafe-perm @flowfuse/node-red-dashboard
|
||||||
|
|
||||||
|
# Copier votre flux si nécessaire
|
||||||
|
COPY flows.json /data/flows.json
|
||||||
571
.devcontainer/nodered/flows.json
Normal file
571
.devcontainer/nodered/flows.json
Normal file
@@ -0,0 +1,571 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "41526b8c80d5a5f7",
|
||||||
|
"type": "tab",
|
||||||
|
"label": "Flux 1",
|
||||||
|
"disabled": false,
|
||||||
|
"info": "",
|
||||||
|
"env": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "dc9d3b99eadb9b34",
|
||||||
|
"type": "ui-button",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"group": "5fe915fcd26e78ae",
|
||||||
|
"name": "",
|
||||||
|
"label": "B0",
|
||||||
|
"order": 2,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"emulateClick": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"color": "",
|
||||||
|
"bgcolor": "",
|
||||||
|
"className": "",
|
||||||
|
"icon": "",
|
||||||
|
"iconPosition": "left",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "str",
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"buttonColor": "",
|
||||||
|
"textColor": "",
|
||||||
|
"iconColor": "",
|
||||||
|
"enableClick": true,
|
||||||
|
"enablePointerdown": false,
|
||||||
|
"pointerdownPayload": "",
|
||||||
|
"pointerdownPayloadType": "str",
|
||||||
|
"enablePointerup": false,
|
||||||
|
"pointerupPayload": "",
|
||||||
|
"pointerupPayloadType": "str",
|
||||||
|
"x": 130,
|
||||||
|
"y": 320,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"6444617c166984e0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9dcd1bf2a25f7371",
|
||||||
|
"type": "ui-button",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"group": "5fe915fcd26e78ae",
|
||||||
|
"name": "",
|
||||||
|
"label": "B1",
|
||||||
|
"order": 3,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"emulateClick": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"color": "",
|
||||||
|
"bgcolor": "",
|
||||||
|
"className": "",
|
||||||
|
"icon": "",
|
||||||
|
"iconPosition": "left",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "str",
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"buttonColor": "",
|
||||||
|
"textColor": "",
|
||||||
|
"iconColor": "",
|
||||||
|
"enableClick": true,
|
||||||
|
"enablePointerdown": false,
|
||||||
|
"pointerdownPayload": "",
|
||||||
|
"pointerdownPayloadType": "str",
|
||||||
|
"enablePointerup": false,
|
||||||
|
"pointerupPayload": "",
|
||||||
|
"pointerupPayloadType": "str",
|
||||||
|
"x": 130,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4ee747c8012c58a1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "143358afb510246e",
|
||||||
|
"type": "ui-button",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"group": "5fe915fcd26e78ae",
|
||||||
|
"name": "",
|
||||||
|
"label": "B2",
|
||||||
|
"order": 4,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"emulateClick": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"color": "",
|
||||||
|
"bgcolor": "",
|
||||||
|
"className": "",
|
||||||
|
"icon": "",
|
||||||
|
"iconPosition": "left",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "str",
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"buttonColor": "",
|
||||||
|
"textColor": "",
|
||||||
|
"iconColor": "",
|
||||||
|
"enableClick": true,
|
||||||
|
"enablePointerdown": false,
|
||||||
|
"pointerdownPayload": "",
|
||||||
|
"pointerdownPayloadType": "str",
|
||||||
|
"enablePointerup": false,
|
||||||
|
"pointerupPayload": "",
|
||||||
|
"pointerupPayloadType": "str",
|
||||||
|
"x": 130,
|
||||||
|
"y": 400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d966ba0d813b7cb7"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e863fe498c528076",
|
||||||
|
"type": "ui-button",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"group": "5fe915fcd26e78ae",
|
||||||
|
"name": "",
|
||||||
|
"label": "B3",
|
||||||
|
"order": 5,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"emulateClick": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"color": "",
|
||||||
|
"bgcolor": "",
|
||||||
|
"className": "",
|
||||||
|
"icon": "",
|
||||||
|
"iconPosition": "left",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "str",
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"buttonColor": "",
|
||||||
|
"textColor": "",
|
||||||
|
"iconColor": "",
|
||||||
|
"enableClick": true,
|
||||||
|
"enablePointerdown": false,
|
||||||
|
"pointerdownPayload": "",
|
||||||
|
"pointerdownPayloadType": "str",
|
||||||
|
"enablePointerup": false,
|
||||||
|
"pointerupPayload": "",
|
||||||
|
"pointerupPayloadType": "str",
|
||||||
|
"x": 130,
|
||||||
|
"y": 440,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"501355b0c82cae08"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "04e097a5c78127cb",
|
||||||
|
"type": "mqtt out",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "",
|
||||||
|
"topic": "geii/in",
|
||||||
|
"qos": "",
|
||||||
|
"retain": "",
|
||||||
|
"respTopic": "",
|
||||||
|
"contentType": "",
|
||||||
|
"userProps": "",
|
||||||
|
"correl": "",
|
||||||
|
"expiry": "",
|
||||||
|
"broker": "5bf949eb0a1b50a7",
|
||||||
|
"x": 730,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d12767fc3e33bb20",
|
||||||
|
"type": "ui-button",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"group": "5fe915fcd26e78ae",
|
||||||
|
"name": "",
|
||||||
|
"label": "MARCHE",
|
||||||
|
"order": 1,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"emulateClick": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"color": "",
|
||||||
|
"bgcolor": "",
|
||||||
|
"className": "",
|
||||||
|
"icon": "",
|
||||||
|
"iconPosition": "left",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "str",
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"buttonColor": "",
|
||||||
|
"textColor": "",
|
||||||
|
"iconColor": "",
|
||||||
|
"enableClick": true,
|
||||||
|
"enablePointerdown": false,
|
||||||
|
"pointerdownPayload": "",
|
||||||
|
"pointerdownPayloadType": "str",
|
||||||
|
"enablePointerup": false,
|
||||||
|
"pointerupPayload": "",
|
||||||
|
"pointerupPayloadType": "str",
|
||||||
|
"x": 140,
|
||||||
|
"y": 260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3e0c75aae8971dca"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0ca8f4a10a6048af",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "format mqtt",
|
||||||
|
"func": "let marche = Number(flow.get(\"marche\") || 0);\nlet b0 = Number(flow.get(\"b0\") || 0);\nlet b1 = Number(flow.get(\"b1\") || 0);\nlet b2 = Number(flow.get(\"b2\") || 0);\n\nmsg.payload = {\n \"marche\": marche,\n \"b0\": b0,\n \"b1\": b1,\n \"b2\": b2\n};\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 570,
|
||||||
|
"y": 120,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"04e097a5c78127cb"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a49263451d77f972",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": true,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 110,
|
||||||
|
"y": 40,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d28f31d7c379f3d8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d28f31d7c379f3d8",
|
||||||
|
"type": "change",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "marche",
|
||||||
|
"pt": "flow",
|
||||||
|
"to": "0",
|
||||||
|
"tot": "num"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "b1",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "0",
|
||||||
|
"tot": "num"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 320,
|
||||||
|
"y": 40,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3e0c75aae8971dca",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "set marche",
|
||||||
|
"func": "flow.set(\"marche\", !Number(flow.get(\"marche\")));\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 310,
|
||||||
|
"y": 260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6444617c166984e0",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "set marche",
|
||||||
|
"func": "flow.set(\"b0\", !Number(flow.get(\"b0\")));\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 310,
|
||||||
|
"y": 320,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4ee747c8012c58a1",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "set marche",
|
||||||
|
"func": "flow.set(\"b1\", !Number(flow.get(\"b1\")));\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 310,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d966ba0d813b7cb7",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "set marche",
|
||||||
|
"func": "flow.set(\"b2\", !Number(flow.get(\"b2\")));\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 310,
|
||||||
|
"y": 400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "501355b0c82cae08",
|
||||||
|
"type": "function",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "set marche",
|
||||||
|
"func": "flow.set(\"b3\", !Number(flow.get(\"b3\")));\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 310,
|
||||||
|
"y": 440,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"0ca8f4a10a6048af"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1dfea06c14d2732c",
|
||||||
|
"type": "mqtt in",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "",
|
||||||
|
"topic": "geii/out",
|
||||||
|
"qos": "2",
|
||||||
|
"datatype": "auto-detect",
|
||||||
|
"broker": "5bf949eb0a1b50a7",
|
||||||
|
"nl": false,
|
||||||
|
"rap": true,
|
||||||
|
"rh": 0,
|
||||||
|
"inputs": 0,
|
||||||
|
"x": 130,
|
||||||
|
"y": 580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"31ef90b8227cd6cb"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "31ef90b8227cd6cb",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "41526b8c80d5a5f7",
|
||||||
|
"name": "debug 1",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 380,
|
||||||
|
"y": 580,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5fe915fcd26e78ae",
|
||||||
|
"type": "ui-group",
|
||||||
|
"name": "Pupitre",
|
||||||
|
"page": "bb436fe040268d40",
|
||||||
|
"width": "2",
|
||||||
|
"height": 1,
|
||||||
|
"order": 1,
|
||||||
|
"showTitle": true,
|
||||||
|
"className": "",
|
||||||
|
"visible": "true",
|
||||||
|
"disabled": "false",
|
||||||
|
"groupType": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5bf949eb0a1b50a7",
|
||||||
|
"type": "mqtt-broker",
|
||||||
|
"name": "",
|
||||||
|
"broker": "rabbitmq",
|
||||||
|
"port": 1883,
|
||||||
|
"clientid": "",
|
||||||
|
"autoConnect": true,
|
||||||
|
"usetls": false,
|
||||||
|
"protocolVersion": 4,
|
||||||
|
"keepalive": 60,
|
||||||
|
"cleansession": true,
|
||||||
|
"autoUnsubscribe": true,
|
||||||
|
"birthTopic": "",
|
||||||
|
"birthQos": "0",
|
||||||
|
"birthRetain": "false",
|
||||||
|
"birthPayload": "",
|
||||||
|
"birthMsg": {},
|
||||||
|
"closeTopic": "",
|
||||||
|
"closeQos": "0",
|
||||||
|
"closeRetain": "false",
|
||||||
|
"closePayload": "",
|
||||||
|
"closeMsg": {},
|
||||||
|
"willTopic": "",
|
||||||
|
"willQos": "0",
|
||||||
|
"willRetain": "false",
|
||||||
|
"willPayload": "",
|
||||||
|
"willMsg": {},
|
||||||
|
"userProps": "",
|
||||||
|
"sessionExpiry": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bb436fe040268d40",
|
||||||
|
"type": "ui-page",
|
||||||
|
"name": "LP SARII",
|
||||||
|
"ui": "92537b03143c5e06",
|
||||||
|
"path": "/page1",
|
||||||
|
"icon": "home",
|
||||||
|
"layout": "grid",
|
||||||
|
"theme": "ea2bf5532fa513eb",
|
||||||
|
"breakpoints": [
|
||||||
|
{
|
||||||
|
"name": "Default",
|
||||||
|
"px": "0",
|
||||||
|
"cols": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tablet",
|
||||||
|
"px": "576",
|
||||||
|
"cols": "6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Small Desktop",
|
||||||
|
"px": "768",
|
||||||
|
"cols": "9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Desktop",
|
||||||
|
"px": "1024",
|
||||||
|
"cols": "12"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"order": 1,
|
||||||
|
"className": "",
|
||||||
|
"visible": "true",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "92537b03143c5e06",
|
||||||
|
"type": "ui-base",
|
||||||
|
"name": "My Dashboard",
|
||||||
|
"path": "/dashboard",
|
||||||
|
"appIcon": "",
|
||||||
|
"includeClientData": true,
|
||||||
|
"acceptsClientConfig": [
|
||||||
|
"ui-notification",
|
||||||
|
"ui-control"
|
||||||
|
],
|
||||||
|
"showPathInSidebar": false,
|
||||||
|
"headerContent": "page",
|
||||||
|
"navigationStyle": "default",
|
||||||
|
"titleBarStyle": "default",
|
||||||
|
"showReconnectNotification": true,
|
||||||
|
"notificationDisplayTime": 1,
|
||||||
|
"showDisconnectNotification": true,
|
||||||
|
"allowInstall": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ea2bf5532fa513eb",
|
||||||
|
"type": "ui-theme",
|
||||||
|
"name": "Default Theme",
|
||||||
|
"colors": {
|
||||||
|
"surface": "#ffffff",
|
||||||
|
"primary": "#0094CE",
|
||||||
|
"bgPage": "#eeeeee",
|
||||||
|
"groupBg": "#ffffff",
|
||||||
|
"groupOutline": "#cccccc"
|
||||||
|
},
|
||||||
|
"sizes": {
|
||||||
|
"density": "default",
|
||||||
|
"pagePadding": "12px",
|
||||||
|
"groupGap": "12px",
|
||||||
|
"groupBorderRadius": "4px",
|
||||||
|
"widgetGap": "12px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "925a608e1a2d82a3",
|
||||||
|
"type": "global-config",
|
||||||
|
"env": [],
|
||||||
|
"modules": {
|
||||||
|
"@flowfuse/node-red-dashboard": "1.29.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build/
|
||||||
25
.vscode/launch.json
vendored
Normal file
25
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug pompes",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/pompes",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Activer les pretty-printers pour gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "CMake: build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.insertFinalNewline": true,
|
||||||
|
"files.trimTrailingWhitespace": true,
|
||||||
|
"files.trimFinalNewlines": true
|
||||||
|
}
|
||||||
21
.vscode/tasks.json
vendored
Normal file
21
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "CMake: build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cmake --build build --config Debug",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": ["$gcc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "CMake: configure",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
||||||
|
"problemMatcher": ["$gcc"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
59
CMakeLists.txt
Normal file
59
CMakeLists.txt
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
project(pompes LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
# Activer warnings utiles
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
|
||||||
|
|
||||||
|
# Executable principal
|
||||||
|
add_executable(pompes
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Librairies systèmes
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
# CURL
|
||||||
|
find_package(CURL REQUIRED)
|
||||||
|
|
||||||
|
# Microhttpd
|
||||||
|
find_library(MICROHTTPD_LIB microhttpd REQUIRED)
|
||||||
|
|
||||||
|
# Threads et compression
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
find_library(Z_LIB z REQUIRED)
|
||||||
|
|
||||||
|
# ncursesw
|
||||||
|
find_library(NCURSESW_LIB ncursesw REQUIRED)
|
||||||
|
|
||||||
|
# RabbitMQ C client
|
||||||
|
find_library(RABBITMQ_LIB rabbitmq REQUIRED)
|
||||||
|
|
||||||
|
# Paho MQTT C client
|
||||||
|
find_library(PAHO_MQTTPP3_LIB paho-mqttpp3 REQUIRED)
|
||||||
|
find_library(PAHO_MQTT3C_LIB paho-mqtt3c REQUIRED)
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Prometheus C++
|
||||||
|
# -------------------------------
|
||||||
|
find_package(prometheus-cpp REQUIRED)
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Lien des bibliothèques
|
||||||
|
# -------------------------------
|
||||||
|
target_link_libraries(pompes
|
||||||
|
prometheus-cpp::core
|
||||||
|
prometheus-cpp::pull
|
||||||
|
${CURL_LIBRARIES}
|
||||||
|
${MICROHTTPD_LIB}
|
||||||
|
Threads::Threads
|
||||||
|
${Z_LIB}
|
||||||
|
${NCURSESW_LIB}
|
||||||
|
${RABBITMQ_LIB}
|
||||||
|
${PAHO_MQTT3C_LIB} # dépendance C
|
||||||
|
${PAHO_MQTTPP3_LIB} # lib C++
|
||||||
|
)
|
||||||
496
autom.cpp
Normal file
496
autom.cpp
Normal file
@@ -0,0 +1,496 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#undef timeout
|
||||||
|
#include "mqtt/async_client.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
// 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
PinIO _digital[256];
|
||||||
|
|
||||||
|
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<int>() != 0;
|
||||||
|
|
||||||
|
std::cout << "boutons : " << s0 << std::endl;
|
||||||
|
}
|
||||||
|
catch (const json::parse_error &e)
|
||||||
|
{
|
||||||
|
std::cerr << "Erreur JSON : " << e.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// ************************************************************
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
json obj = {
|
||||||
|
{"s0", s0},
|
||||||
|
{"s1", s1},
|
||||||
|
{"s2", 0},
|
||||||
|
{"s3", 1},
|
||||||
|
{"s4", 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string payload = obj.dump();
|
||||||
|
auto msg = mqtt::make_message("geii/out", payload);
|
||||||
|
msg->set_qos(0);
|
||||||
|
client.publish(msg);
|
||||||
|
|
||||||
|
std::cout << s0 << std::endl;
|
||||||
|
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ********************************************************
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
16
main.cpp
Normal file
16
main.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <array>
|
||||||
|
#include "main.hpp"
|
||||||
|
#include "autom.cpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
open();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
|
||||||
|
close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user