---
module: agent.tcr-events
title: TCR Events — cassette + sensor + process monitoring for Teller Cash Recyclers
tab: Claude
order: 40
audience: dev
---

> **Claude · terse act-without-guessing reference.** From compiled `hiveops-module-tcr-events` v4.3.5 (`.java` not in tree; read from bytecode + core `IncidentEventClient`/`HttpClientHelper`).

## Identity

- Maven artifact / JAR: `hiveops-module-tcr-events` (groupId `com.hiveops`, built v`4.3.5`).
- Agent module id (`getName()`): `tcr-events`. Module `getVersion()`: `1.0.0`.
- SPI: `com.hiveops.core.module.AgentModule` → `com.hiveops.tcrevents.TcrEventsModule`.
- Classes: `TcrEventsModule`, `TcrAccessLogMonitor`, `CstSnsLogMonitor`, `TcrCassetteMonitor` (pkg `com.hiveops.tcrevents`).
- Shares module id `tcr-events` with `hiveops-module-atec-tcr-events`; **this is the superset** (adds cassette-JSON monitor). Never install both on one device.

## Config keys (from `hiveops.properties`)

| Key | Default | Notes |
|---|---|---|
| `device.type` | `ATM` | Must be `ATEC_TCR` or `TCR` (upper-cased) or module disables. |
| `tcr.events.enabled` | `true` | Anything != `true` (ci) disables. |
| `tcr.log.dir` | *(required)* | Dir of the 3 log files. Missing key → disabled; missing dir → warn + retry. |
| `tcr.events.poll.interval.sec` | `30` | Scheduler period (seconds). |
| `agent.endpoint` | *(none)* | Present → HTTP prefix `agent`; absent → prefix `incident`. |
| `agent.auth.token` | — | Bearer for all requests (not module-specific). |

## Watched files (daily, `MMdd`)

- `ACESSLog<MMdd>.txt` — `TcrAccessLogMonitor` (note the misspelling "ACESS", it's the vendor's).
- `CST_SNR_<MMdd>.log` — `CstSnsLogMonitor`.
- `JsonLog_<MMdd>.json` — `TcrCassetteMonitor` (only `"Command":"RU"` lines).

## Event strings emitted

`eventType` (exact):
- `TCR_PROCESS_RESTART`
- `TCR_SHUTDOWN`
- `CASSETTE_EMPTY`
- `TCR_SENSOR_FAULT`
- `TCR_MANUAL_REQUIRED`
- `TCR_SENSOR_MISMATCH`
- `CASSETTE_INVENTORY`

`eventSource` (exact): `TCR_ACESS_LOG`, `TCR_CST_SNR`, `TCR_CASSETTE`.

Sensor state codes → events: `EMPT`→`CASSETTE_EMPTY`, `SNRF`→`TCR_SENSOR_FAULT`, `TMAN`→`TCR_MANUAL_REQUIRED`, `NORM`→**recovery, no event**.

Cassette type map: `Recycle_Cassette`→`RECYCLE`, `Operation_Cassette`→`OPERATION`, `Reject_Cassette`→`REJECT`. Status values: `Available`/`Low`/`Empty`/`Full`.

## Transport

- `IncidentEventClient.sendEvent` → `POST {endpoint}/api/journal-events`, accepts 200/201/202.
- Auto-register via `agentAtmId`; do NOT rely on `resolveAtmId()` (deprecated).
- Endpoint from `agent.endpoint` (prefix `agent`, agent-proxy `/agent`) else `incident.endpoint`.

## Gotchas

- Monitors set **no** `deviceType` on the request → backend records events as ATM default, not TCR.
- No offset persistence — agent restart re-reads current day's file from 0 (append-only vendor logs mitigate dupes; midnight rollover switches filename automatically).
- Poll errors are caught/logged (`tcr-events: poll error:`), never fatal.
- No `PlatformService` — pure `java.nio` + `RandomAccessFile("r")`; identical across OSes given same log dir.
- Deploy/retrofit: fleet `INSTALL_MODULE` task (drops JAR into `modules/`, restarts agent) or full standard-set agent update.

## Do NOT

- Do NOT expect events on a device unless `device.type=ATEC_TCR|TCR` AND `tcr.log.dir` is set.
- Do NOT install alongside `hiveops-module-atec-tcr-events` (same module id).
- Do NOT invent config keys — only the five above are read. No `tcr-events.*`-dotted keys exist; the real prefixes are `tcr.events.*` and `tcr.log.dir`.
- Do NOT assume batch upload — events post one-by-one per `sendEvent`.
- Do NOT trust `getVersion()`=`1.0.0` as the release version; the shipped artifact version is the agent build (`4.3.5` here).
