Source code for OzWrapper.OzOGS.OzOGS_Allocation
1"""Standalone factory allocation harness for the OGS array.
2
3Boots an instance of :class:`OzWrapper.OzOGS.OzOGS.OzOGS` outside the
4main Sensor orchestrator, drives one reading cycle at a time on demand
5via MQTT control topics on ``broker.hivemq.com``, and reflects state on
6the front-panel RGB LED through :class:`OzWrapper.OzRGB.OzRGB`. Used on
7the factory bench when commissioning a new gas-sensor board and
8producing the slot-to-gas allocation map that the runtime configuration
9will eventually carry.
10
11MQTT topics:
12 * ``/ogs/start`` (sub) - trigger one read+publish cycle.
13 * ``/ogs/restart`` (sub) - reinitialise the OGS wrapper.
14 * ``/ogs/ledstatus`` (pub) - human-readable status string.
15 * ``/ogs/data`` (pub) - averaged readings as JSON.
16
17Example:
18 >>> import OzWrapper.OzOGS.OzOGS_Allocation # doctest: +SKIP
19
20Note:
21 Reads its OGS configuration from ``allocation_ogs.json`` co-located
22 with this module. See :mod:`OzWrapper.OzOGS.OzOGS` for the sensor
23 wrapper contract this script drives, and the same module's
24 reference JSON for the expected ``ogs`` configuration shape.
25"""
26
27import json
28import os
29
30import paho.mqtt.client as paho
31
32from drivers.MCP230XX import MCP230XX
33from OzWrapper.OzOGS import OzOGS
34
35flagStart = False
36restartFlag = True
37# ledstatusFlag = True
38
39import threading
40from queue import Queue
41
42from OzWrapper.OzRGB import OzRGB
43
44
[docs]
45def on_subscribe(client, userdata, mid, granted_qos):
46 """Log MQTT subscription acknowledgements from the broker.
47
48 Standard ``paho.mqtt`` ``on_subscribe`` callback signature; emits
49 a single ``Subscribed: <mid> <qos>`` line so the operator can
50 confirm that ``/ogs/start`` and ``/ogs/restart`` are wired up.
51
52 Args:
53 client: The :class:`paho.mqtt.client.Client` instance.
54 userdata: User-defined data set on the client (unused).
55 mid (int): Message ID of the subscribe request.
56 granted_qos (list[int]): QoS levels granted per topic by the
57 broker.
58
59 Returns:
60 None: Side effect only - prints to stdout.
61
62 Raises:
63 None: All work is a single print call.
64
65 Example:
66 >>> on_subscribe(client, None, 1, [1]) # doctest: +SKIP
67
68 Note:
69 Wired up at module import time on the global ``client``.
70 """
71 print("Subscribed: " + str(mid) + " " + str(granted_qos))
72
73
[docs]
74def on_message(client, userdata, msg):
75 """Route incoming MQTT control messages into the allocation loop.
76
77 Sets the module-global flags consumed by the main loop in
78 ``__main__``:
79
80 * ``/ogs/start`` -> ``flagStart = True`` (triggers one read+publish).
81 * ``/ogs/restart`` -> ``restartFlag = True`` (reinitialises
82 :class:`OzWrapper.OzOGS.OzOGS.OzOGS`).
83
84 Args:
85 client: The :class:`paho.mqtt.client.Client` instance.
86 userdata: User-defined data set on the client (unused).
87 msg (paho.mqtt.client.MQTTMessage): Incoming message; ``topic``,
88 ``qos`` and ``payload`` are inspected. The payload itself is
89 ignored for routing - only ``topic`` matters.
90
91 Returns:
92 None: Mutates module-level flags.
93
94 Raises:
95 None: All branches are simple flag assignments.
96
97 Example:
98 >>> client.publish("/ogs/start", "") # doctest: +SKIP
99
100 Note:
101 The ``/ogs/ledstatus`` branch is intentionally commented out
102 because the LED status flag is now driven by the main loop
103 directly, not by an external trigger.
104 """
105 print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
106 if msg.topic == "/ogs/start":
107 print("start")
108 global flagStart
109 flagStart = True
110 elif msg.topic == "/ogs/restart":
111 print("restart")
112 global restartFlag
113 restartFlag = True
114 # elif msg.topic == "/ogs/ledstatus":
115 # global ledstatusFlag
116 # ledstatusFlag = True
117
118
119client = paho.Client()
120client.on_subscribe = on_subscribe
121client.on_message = on_message
122client.connect("broker.hivemq.com", 1883)
123client.subscribe("/ogs/start", qos=1)
124client.subscribe("/ogs/restart", qos=1)
125# client.subscribe("/ogs/ledstatus", qos=1)
126client.loop_start()
127
128
129# Example code
130# python3 -m OzWrapper.OzOGS.OzOGS
131if __name__ == "__main__":
132 network_status = Queue(2)
133 network_status.put(0) # 0-th element
134 network_status.put(0) # 1st Element
135 Led_rgb = OzRGB
136 MCP = MCP230XX(devicenumber=os.getenv("MCP_ID", 6))
137 led_Thread = threading.Thread(target=Led_rgb.main, args=(None, network_status), daemon=True)
138 led_Thread.start()
139 network_status.queue[0] = 7 # neon orange
140 dirname = os.path.dirname(__file__)
141 file_name = os.path.join(dirname, "allocation_ogs.json")
142 with open(file_name) as ogsConfigFile:
143 data = ogsConfigFile.read()
144 ogsConfig = json.loads(data)
145 print(ogsConfig)
146 ogs = None
147 while True:
148 network_status.queue[0] = 2 # Blue pattern slow blink in idle condition
149 LED_Status = ""
150 if restartFlag == True:
151 ogs = None
152 network_status.queue[0] = 7 # neon orange
153 LED_Status = ""
154 LED_Status = "OGS init started"
155 client.publish("/ogs/ledstatus", LED_Status)
156 ogs = OzOGS()
157 init_value = {}
158 ogs.initialize(ogsConfig["ogs"], init_value)
159 restartFlag = False
160 LED_Status = "Idle Condition"
161 client.publish("/ogs/ledstatus", LED_Status)
162
163 if flagStart == True:
164 LED_Status = ""
165 LED_Status = "OGS read started"
166 client.publish("/ogs/ledstatus", LED_Status)
167 if flagStart:
168 network_status.queue[0] = 1 # cyan, pattern_fade, while reading data from ADS-UART
169 print("Reading start \n\n")
170 for i in range(0, 3):
171 ogs.getSensorReading()
172 network_status.queue[0] = 3 # magenta, pattern_fade while uploading data
173 data = {}
174 print("PutSensor value start \n\n")
175 ogs.putSensorValue(data)
176 for key in list(data):
177 data.update({key: round(sum(data[key]) / len(data[key]), 2)})
178 print(data)
179 flagStart = False
180 client.publish("/ogs/data", json.dumps(data))
181 LED_Status = "Idle Condition"
182 client.publish("/ogs/ledstatus", LED_Status)
183
184 # if ledstatusFlag==True:
185 # client.publish('/ogs/ledstatus', LED_Status)
186 # ledstatusFlag = False