[Perl] DAQ system for the FAPG.
Update README.
README.org
@@ -4,10 +4,10 @@
4
4
5
5
* Overview
6
6
7
Removed:
The goal of this project is to deploy a DAQ network at the FAPG.
8
Removed:
Sensor nodes periodically send readings to a central DAQ hub. An
9
Removed:
external VPS obtains these readings, and displays them on a web
10
Removed:
dashboard.
7
Added:
The goal of this project is to deploy a DAQ network at the /Ferme
8
Added:
Aquaponique du Pays de Gex/ (FAPG). DAQ sensor nodes periodically
9
Added:
send readings to a central DAQ hub. An external VPS obtains these
10
Added:
readings, and presents them on a dashboard accessible via the web.
11
11
12
12
* Architecture
13
13
@@ -17,7 +17,7 @@
17
17
18
18
actor "Farm user/browser" as Browser
19
19
20
Removed:
participant "EZO probe\npH / EC / DO / Redox" as Probe
20
Added:
participant "EZO probe\npH / EC / DO / ORP" as Probe
21
21
participant "Pi Zero 2W\nfapg-daq service" as Zero
22
22
participant "Pi 5\nMosquitto MQTT broker" as Broker
23
23
participant "VPS\nMQTT subscriber service" as VPSSubscriber
@@ -33,28 +33,40 @@
33
33
34
34
== MQTT publication ==
35
35
36
Removed:
Zero -> Broker : MQTT PUBLISH\nfapg/daq/<probe>/<node>/reading\nJSON payload
36
Added:
Zero -> Broker : MQTT PUBLISH\nfapg/daq/<probe>/<node>/reading\nvalid reading JSON payload
37
Added:
Zero -> Broker : MQTT PUBLISH\nfapg/daq/<probe>/<node>/status\nnode/probe status JSON payload
37
38
38
39
note right of Zero
39
Removed:
Example payload:
40
Removed:
{
41
Removed:
"schema": "fapg.daq.reading.v1",
42
Removed:
"node": "fapg-zero-ph-01",
43
Removed:
"probe": "ph",
44
Removed:
"value": 7.12,
45
Removed:
"unit": "pH",
46
Removed:
"timestamp": "2026-06-27T13:45:00Z"
47
Removed:
}
40
Added:
Example reading payload:
41
Added:
{
42
Added:
"schema": "fapg.daq.reading.v1",
43
Added:
"node": "fapg-zero-ph-01",
44
Added:
"probe": "ph",
45
Added:
"value": 7.12,
46
Added:
"unit": "pH",
47
Added:
"timestamp": "2026-06-27T13:45:00Z"
48
Added:
}
49
Added:
50
Added:
Example status payload:
51
Added:
{
52
Added:
"schema": "fapg.daq.status.v1",
53
Added:
"node": "fapg-zero-ph-01",
54
Added:
"probe": "ph",
55
Added:
"status": "probe_error",
56
Added:
"timestamp": "2026-06-27T13:45:05Z",
57
Added:
"error": "timeout waiting for EZO response"
58
Added:
}
48
59
end note
49
60
50
Removed:
VPSSubscriber -> Broker : MQTT SUBSCRIBE\nfapg/daq/+/+/reading
51
Removed:
Broker --> VPSSubscriber : MQTT MESSAGE\nreading topic + JSON payload
61
Added:
VPSSubscriber -> Broker : MQTT SUBSCRIBE\nfapg/daq/#
62
Added:
Broker --> VPSSubscriber : MQTT MESSAGE\nreading/status topic + JSON payload
52
63
53
Removed:
VPSSubscriber -> VPSSubscriber : Validate topic and payload\nparse probe, node, value, timestamp
64
Added:
VPSSubscriber -> VPSSubscriber : Validate topic and payload\nparse probe, node, value/status, timestamp
54
65
55
66
== Database storage ==
56
67
57
68
VPSSubscriber -> DB : INSERT reading
69
Added:
VPSSubscriber -> DB : INSERT node status
58
70
DB --> VPSSubscriber : OK
59
71
60
72
== Live dashboard presentation ==
@@ -100,3 +112,24 @@
100
112
This host establishes a VPN connection with the Pi 5 host, subscribes
101
113
to all MQTT topics, saves messages to a database, and exposes a
102
114
realtime web dashboard available over the internet.
115
Added:
116
Added:
** MQTT Topics
117
Added:
118
Added:
Valid probe measurements are published only on:
119
Added:
120
Added:
#+begin_src text
121
Added:
fapg/daq/<probe>/<node>/reading
122
Added:
#+end_src
123
Added:
124
Added:
Node/probe health is published separately on:
125
Added:
126
Added:
#+begin_src text
127
Added:
fapg/daq/<probe>/<node>/status
128
Added:
#+end_src
129
Added:
130
Added:
Status payloads use schema =fapg.daq.status.v1=. A recent =ok=
131
Added:
status means the node is reachable and publishing valid readings. A
132
Added:
recent =probe_error= status means the node is reachable on the farm
133
Added:
network, but the probe or USB serial path is not returning a valid
134
Added:
reading. If the dashboard has no recent status for a node, it treats
135
Added:
that node as unreachable.