---
module: agent.atm-config-sync
title: ATM Config Sync — pushes ATM hardware/software/cassette config to the platform
tab: Claude
order: 40
audience: dev
---

> **Internal · agent reference.** Terse. Confirmed against `hiveops-module-atm-config-sync` source 2026-07-01.

## Identity
- Maven artifact: **`hiveops-module-atm-config-sync`** (`com.hiveops`, version `1.0.0`, packaged as a standalone `jar`, parent `hiveops-agent-parent` `4.4.3`).
- Agent module id (`getName()`, and the string for **`modules.disabled`**): **`device-config-sync`** — NOT `atm-config-sync`.
- Entry class: `com.hiveops.configsync.AtmConfigSyncModule`, registered via `META-INF/services/com.hiveops.core.module.AgentModule`.
- Log package (`getLogPackage()`): `com.hiveops.configsync`.
- Dependencies (`getDependencies()`): none (empty list).
- Single class — no separate monitor/parser classes of its own.

## Behavior (not an event/log-tail module)
- Emits **NO** journal/incident events. Sends one consolidated config payload.
- `isEnabled()` = `ready` = true only if `agent.endpoint` OR `incident.endpoint` resolved at `initialize()`. No `device.type` gate, no dedicated enable flag.
- Sync triggers: (1) once at `initialize()`; (2) every **6h** fixed-rate (`RESYNC_INTERVAL_HOURS=6`, initialDelay 0, daemon thread `config-resync`); (3) on-demand via **`RESYNC_CONFIG`** fleet command → `ConfigResyncRegistry.trigger()`.
- Each sync calls `ConnectionStateTracker.awaitReconnectJitter()` first (post-reconnect anti-stampede).
- Failure = logged (`ATM config sync failed: ...`), NOT retried/queued; next 6h tick or `RESYNC_CONFIG` recovers.

## Config properties (exact keys)
| Key | Default | Notes |
|---|---|---|
| `agent.endpoint` | *(none)* | preferred base URL; if set → HTTP prefix `agent` |
| `incident.endpoint` | *(none)* | legacy fallback; used only if `agent.endpoint` unset → prefix `incident`. Neither set → module disabled |
| `incident.institution.key` | *(none)* | stamped on payload. Reads ONLY this key (not `agent.institution.key`) |
| `applog.events.dir` | *(none)* | dir for applog file; unset → Hyosung version + system info skipped |
| `applog.events.filename.format` | `APLog{YYYY}{MM}{DD}.log` | applog filename pattern |
| `moniplus2s.dir` | Win fallback `C:\Hyosung\MoniPlus2S` | if value isn't a real dir (backslash stripping) → warn + Windows default |

Bearer token / HTTP params: shared `HttpClientHelper.loadSettingsFromProperties(props, prefix)` (`agent.auth.token` chain). No module-specific auth.

## Transport (exact)
- Method: `IncidentEventClient.syncConfig(AtmConfigSyncRequest)`.
- Endpoint: **`POST {endpoint}/api/atms/config/sync`** (NOT `/api/journal-events`).
- Body: Jackson-serialized `AtmConfigSyncRequest` (`com.hiveops.events.dto`).
- Success: HTTP 200/201/202; else throws `IOException`.
- Backend resolves device by `atmName` + `country` in body.

## Payload fields (`AtmConfigSyncRequest`)
- Identity: `atmName`, `country`, `agentVersion`, `timezone` (`TimeZone.getDefault().getID()`), `institutionKey`, `startupDetectionMethod` (from `startup-info.properties` → `startup.detection.method`).
- Versions (platform `ConfigurationReader`): `systemName`, `customizingVersion`, `hotfixVersion`, `countrySpecificVersion`.
- `cassettes`: `List<CassetteConfig>{position, currency, denomination}` from `readCassetteDenominations()`; fallback = MoniPlus2S `HostNoteTypes` parse only if still empty.
- `hyosungVersion` (`HyosungVersionParser`): app/SDK/GSDK/Nextware/componentVersions.
- `systemInfo` (`AppLogHeaderParser`): OS + installed programs/packages.
- `moniplus2sConfig` + `moniplus2sLayeredConfig` (`MoniPlus2SConfigParser.parse()` / `.parseAllLayers()`).

## Deployment
- Delivered via **`INSTALL_MODULE`** fleet task (drops JAR into agent `modules/` dir — `ProcessInstallModule` in `hiveops-file-collection`).
- Disable without uninstall: add `device-config-sync` to `modules.disabled`, push `CONFIG_UPDATE`.
- Force immediate resync: `RESYNC_CONFIG` fleet command (no restart).

## Do NOT
- Do NOT use `atm-config-sync` as the `modules.disabled` value — the real id is **`device-config-sync`**.
- Do NOT look for emitted events — this module sends config, not `*_EVENT`s; there are no event-type strings.
- Do NOT expect it to POST to `/api/journal-events` — it uses `/api/atms/config/sync`.
- Do NOT expect `agent.institution.key` to be picked up for the payload — only `incident.institution.key` is read here.
- Do NOT put a single-backslash Windows path in `moniplus2s.dir` — properties strip it; double the backslashes or rely on the `C:\Hyosung\MoniPlus2S` default.
- Do NOT expect send failures to retry — they're logged and dropped; recovery is the next 6h tick / `RESYNC_CONFIG`.
- Do NOT assume `RESYNC_CONFIG` works if this module is disabled — it's the sole `ConfigResyncRegistry` registrant; disabled → `trigger()` no-ops with a warning.
- Do NOT expect a `device.type`/enable gate — the only gate is "an endpoint is configured."
