From 237474adfd4b7edbaedb19216743b82f712a7180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20Etxaniz?= Date: Fri, 2 Oct 2026 19:48:15 +0200 Subject: [PATCH] Initial content, migrated from the aml gateway rpi7-am-1 --- README.md | 16 +++++- bar_tracker.py | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ schedule.yaml | 11 +++++ signals.yml | 3 ++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 bar_tracker.py create mode 100644 schedule.yaml create mode 100644 signals.yml diff --git a/README.md b/README.md index b024544..55c77d5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ # bar-tracker -Records each bar's entry, exit and exit temperature in the oven_bar tables \ No newline at end of file +Runs continuously, once a second. Watches the pulses `bar-detection` writes and keeps the +oven's bar record in the customer database: + +- On a rising edge of `in-detect-oven` (11) it inserts a row in `oven_bar_enter_detection` + and opens a row in `oven_bar`. +- On a rising edge of `out-detect-oven` (12) it inserts a row in `oven_bar_exit_detection` + and closes the oldest open `oven_bar` row, or inserts a closed one if none is open. It then + reads `THprocess` (17) for five ticks and writes the maximum as `bar_temperature` on both + rows. + +The first tick only records the current values, so a restart never fires a false edge. + +Needs the db-controller reachable from the job's sidecar, and the three `oven_bar*` tables in +the gateway's customer database. Runs in `docker.izazpi.cloud/aml/aml-python`; the version is +in `schedule.yaml`. diff --git a/bar_tracker.py b/bar_tracker.py new file mode 100644 index 0000000..a8c6ded --- /dev/null +++ b/bar_tracker.py @@ -0,0 +1,130 @@ +from i7lib.client import run +from i7lib.dbutils import Database +from i7lib.timeutils import now, to_datetime + +db = Database() +prev_in = None +prev_out = None +temp_measurement = None + + +def log(msg): + ts = now() + dt = to_datetime(ts).strftime("%Y-%m-%d %H:%M:%S") + print(f"[{dt}] {msg}") + + +def record_enter_detection(instant): + result = db.insert("oven_bar_enter_detection", {"detected_time": instant, "deleted": 0, "deleted_time": 0}) + if result: + log(f"detection recorded in oven_bar_enter_detection, id={result['id']}") + else: + log("ERROR: detection insert failed in oven_bar_enter_detection") + + +def record_exit_detection(instant): + result = db.insert("oven_bar_exit_detection", {"detected_time": instant, "bar_temperature": 0, "deleted": 0, "deleted_time": 0}) + if result: + log(f"detection recorded in oven_bar_exit_detection, id={result['id']}") + else: + log("ERROR: detection insert failed in oven_bar_exit_detection") + return result + + +def handle_entry(instant): + record_enter_detection(instant) + result = db.insert("oven_bar", {"entered_time": instant, "exited_time": 0, "bar_temperature": 0, "deleted": 0, "deleted_time": 0}) + if result: + log(f"bar entered, id={result['id']}") + else: + log("ERROR: insert failed on entry") + + +def find_oldest_open_bar(): + rows = db.query( + "oven_bar", + filters=[ + {"column": "exited_time", "op": "eq", "value": 0}, + {"column": "deleted", "op": "eq", "value": 0}, + ], + order_by=["entered_time"], + limit=1, + ) + if not rows: + return None + r = rows[0] + log(f"oldest open bar: id={r['id']} entered={r['entered_time']}") + return r + + +def handle_exit(instant): + global temp_measurement + det = record_exit_detection(instant) + det_id = det["id"] if det else None + + row = find_oldest_open_bar() + if row: + db.update("oven_bar", row["id"], {"exited_time": instant}) + bar_id = row["id"] + log(f"bar exited, id={bar_id}") + else: + result = db.insert("oven_bar", {"entered_time": instant, "exited_time": instant, "bar_temperature": 0, "deleted": 0, "deleted_time": 0}) + bar_id = result["id"] if result else None + if result: + log(f"bar exited (no open entry), id={bar_id}") + else: + log("ERROR: insert failed on orphan exit") + + temp_measurement = {"det_id": det_id, "bar_id": bar_id, "readings": [], "remaining": 5} + log("started temperature measurement (5 ticks)") + + +def collect_temperature(thprocess): + global temp_measurement + if temp_measurement is None: + return + + temp_measurement["readings"].append(thprocess) + temp_measurement["remaining"] -= 1 + log(f"temp reading: {thprocess} ({temp_measurement['remaining']} remaining)") + + if temp_measurement["remaining"] > 0: + return + + max_temp = max(temp_measurement["readings"]) + log(f"temperature measurement complete, max={max_temp}") + + if temp_measurement["det_id"]: + db.update("oven_bar_exit_detection", temp_measurement["det_id"], {"bar_temperature": max_temp}) + if temp_measurement["bar_id"]: + db.update("oven_bar", temp_measurement["bar_id"], {"bar_temperature": max_temp}) + + temp_measurement = None + + +def logic(plant): + global prev_in, prev_out + sig_in = plant.state.get("in-detect-oven", 0.0) + sig_out = plant.state.get("out-detect-oven", 0.0) + thprocess = plant.state.get("THprocess", 0.0) + + if prev_in is not None: + if sig_in == 1.0 and prev_in == 0.0: + instant_in = plant.instants.get("in-detect-oven", 0) + log(f"RISING EDGE in-detect-oven (prev={prev_in} -> cur={sig_in})") + handle_entry(instant_in) + if sig_out == 1.0 and prev_out == 0.0: + instant_out = plant.instants.get("out-detect-oven", 0) + log(f"RISING EDGE out-detect-oven (prev={prev_out} -> cur={sig_out})") + handle_exit(instant_out) + else: + log(f"first tick, skipping edges (in={sig_in}, out={sig_out})") + + collect_temperature(thprocess) + + prev_in = sig_in + prev_out = sig_out + + +if __name__ == "__main__": + run(logic, interval_ms=1000, offset_ms=200) diff --git a/schedule.yaml b/schedule.yaml new file mode 100644 index 0000000..0541d25 --- /dev/null +++ b/schedule.yaml @@ -0,0 +1,11 @@ +name: bar-tracker +active: true +schedule: "* * * * *" +action: ensure +runOnStartup: true +imageName: docker.izazpi.cloud/aml/aml-python:0.1.0 +command: ["python", "/app/bar_tracker.py"] +maxCpuCores: 0.5 +maxMemoryMb: 128 +autoremove: false +logOption: 1 diff --git a/signals.yml b/signals.yml new file mode 100644 index 0000000..716e5f7 --- /dev/null +++ b/signals.yml @@ -0,0 +1,3 @@ +- { id: 11, name: 'in-detect-oven', read: 1, write: 0 } +- { id: 12, name: 'out-detect-oven', read: 1, write: 0 } +- { id: 17, name: 'THprocess', read: 1, write: 0 }