---
module: agent.atec-tcr-events
title: ATEC TCR Events — cassette + process monitoring for LG Teller Cash Recyclers
tab: Internal
order: 20
audience: dev
---

> **Internal · ops/support.** Written 2026-07-01 from `hiveops-module-atec-tcr-events` source. Verify against code before relying on specifics.

## What this module is

`hiveops-module-atec-tcr-events` (Maven artifact `hiveops-module-atec-tcr-events`, agent module id **`tcr-events`**) is an **agent drop-in module**, not a backend service. It runs inside the HiveIQ Agent process on **ATEC/LG TCR (Teller Cash Recycler) devices only** — Windows-only, and it self-disables unless the ATM's `device.type` is `ATEC_TCR` (legacy alias `TCR`).

It tails two log files the LG TCR software already writes on disk and turns specific lines into HiveIQ journal events sent to the incident pipeline — the module does not talk to the recycler hardware directly, and it does not touch cassette counts/cash totals (that's reconciliation's job, not this module's).

## What it monitors

Two independent pollers, both driven by a single scheduler tick (default every 30s):

1. **`CST_SNR_MMDD.log`** (daily-rotated) — cassette sensor/status log. The module watches for:
   - Per-slot status transitions inside `[N_E]` lines (e.g. `AH: NORM AL: EMPT`) — only emits when a slot's status *changes*, so a slot stuck in `EMPT` doesn't re-fire every poll.
   - A `SNR deposit count ... mismatch` warning line (deposit-count sensor vs. transaction-data mismatch).
2. **`ACESSLog<MMDD>.txt`** (daily-rotated — note the firmware spelling `ACESS` and, in the code, **no underscore** before the date: e.g. `ACESSLog0701.txt`) — TCR process/access log. The module watches for:
   - `Process restarted from abnormal termination`
   - `## Shutdown ##` / `## Shutdown for reboot ##`

Both files are expected in the **same directory**, configured once via `tcr.log.dir`.

## Config properties it registers

| Property | Default | Meaning |
|---|---|---|
| `tcr.events.enabled` | `true` | Master on/off switch for this module (checked in addition to the `device.type` gate). |
| `tcr.log.dir` | *(none — required)* | Directory containing `CST_SNR_<MMDD>.log` and `ACESSLog<MMDD>.txt`. If unset or not a real directory, the module logs a warning and disables itself — it does **not** throw/crash agent startup. |
| `tcr.events.poll.interval.sec` | `30` | Poll interval in seconds. **Known bug:** `initialize()` reads this value only to log it — `start()` schedules the poller with the hardcoded `DEFAULT_POLL_SEC` (30s) regardless of what's configured. Changing this property currently has no effect. |

It also reuses the shared agent HTTP settings — `agent.endpoint` (preferred) or `incident.endpoint` (legacy fallback), `agent.auth.token`, and the institution-key chain (`agent.institution.key` / `incident.institution.key`) — the same properties every other event-reporting module uses. There are no TCR-specific auth properties.

## How it's enabled / deployed

- It only activates on ATMs configured with `device.type=ATEC_TCR` (or the legacy `TCR` value). On any other device type it logs `device.type is '<X>', not ATEC_TCR — module disabled` and does nothing — this is expected, not a bug, on non-TCR machines.
- Delivered like any other agent module: uploaded to the fleet artifact store and pushed via an **`INSTALL_MODULE`** fleet task, which drops the module JAR into the agent's `modules/` directory and restarts the agent service (see `ProcessInstallModule` in `hiveops-file-collection`). Standard rollout order applies: lab ATM → pilot device → fleet.
- Can be disabled fleet-wide without removing the JAR by adding `tcr-events` to the comma-separated `modules.disabled` property and pushing a `CONFIG_UPDATE` (module id for `modules.disabled` is **`tcr-events`**, not `atec-tcr-events` — see Claude doc for the exact string).
- Event types it emits (`CASSETTE_EMPTY`, `TCR_SENSOR_FAULT`, `TCR_MANUAL_REQUIRED`, `TCR_SENSOR_MISMATCH`, `TCR_PROCESS_RESTART`, `TCR_SHUTDOWN`) must exist as rows in hiveops-incident's `event_type` table (Incident → Settings → Event Types) for them to be recognized/labeled properly downstream. `CASSETTE_EMPTY` is a standard type shared with other modules; the five `TCR_*` types are specific to this module and may need to be added manually on a new environment.

## Common failure modes / what to check

- **No TCR events ever appear for a customer ATM** — first check `device.type` on that ATM's config; if it isn't `ATEC_TCR`/`TCR`, the module is intentionally inert. Not a bug.
- **Module loaded but silent** — check `tcr.log.dir` is set and points at a real, existing directory on that machine; a missing/wrong path disables the module at startup with a log warning, no crash.
- **Events stopped after midnight / around log rotation** — both monitors roll to a new `MMDD`-named file at local midnight; if the LG TCR software's file-naming convention ever changes (e.g. non-standard rotation, DST edge case), the module will watch a file that never appears and go silent. Check agent logs for `tcr-events: watching <path>` to confirm which file it's tailing.
- **Events sent but not visible/categorized in Incident** — check that `CASSETTE_EMPTY`, `TCR_SENSOR_FAULT`, `TCR_MANUAL_REQUIRED`, `TCR_SENSOR_MISMATCH`, `TCR_PROCESS_RESTART`, `TCR_SHUTDOWN` are registered in hiveops-incident's Event Types settings — these are DB-driven, not hardcoded in incident's code.
- **HTTP send failures** — `IncidentEventClient.sendEvent()` failures are caught and logged (`tcr-events: failed to send ...`) but not retried or queued; a transient outage silently drops that single event rather than backing it up for a later poll.
- **Slot recovered (NORM) events don't create tickets** — by design; recovery only writes an agent-side log line (`slot {} recovered`), no event is emitted for a return to `NORM`.
