- Correct web UI port (8088 not 8080 in Docker) - Add ZABBIX_API_TOKEN to config table - Document hostname format (yodeck- not yodeck#) - Document visible name format (QRS- prefix) - Add Zabbix 7.x setup requirements (group permissions, admin role) - Document Bearer token auth approach Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this project does
Yodmon is a bridge between the Yodeck digital signage API and Zabbix monitoring. It polls the Yodeck API every 10 minutes, stores player state in SQLite, exposes the data via SNMP v2c (for Zabbix to poll every minute), auto-creates/updates Zabbix hosts, and provides a web dashboard.
Running locally (dev)
pip install flask requests apscheduler
python dev_server.py # web UI at http://localhost:8080
python snmp_test.py # print OID tree to verify SNMP data
python snmp_test.py --filter <name_or_id>
dev_server.py sets DB_PATH to ./data/yodmon.db and skips SNMP (Linux/Docker only).
Running in Docker
docker compose up -d --build # SNMP on :161/udp, web UI on :8088
Edit docker-compose.yml before first run: set APP_HOST to the IP of the Docker host reachable by Zabbix.
Configuration
All settings are environment variables (see app/config.py). Key ones:
| Variable | Default | Purpose |
|---|---|---|
YODECK_API_TOKEN |
— | Token yodeck:<secret> format |
APP_HOST |
127.0.0.1 |
IP Zabbix uses to reach this app's SNMP agent |
ENTERPRISE_OID |
.1.3.6.1.4.1.99999 |
Root OID for all player data |
SNMP_COMMUNITY |
public |
SNMPv2c community string |
ZABBIX_URL |
"" |
Leave empty to disable Zabbix auto-sync |
ZABBIX_API_TOKEN |
"" |
Preferred auth (Zabbix 5.4+, required for 6.4+) |
ZABBIX_USER / ZABBIX_PASSWORD |
— | Fallback auth when no API token |
DB_PATH |
/data/yodmon.db |
SQLite file path |
Architecture
Yodeck API (every 10 min)
└── app/scheduler.py → app/yodeck.py fetches all screens (paginated)
→ app/database.py upserts players + writes logs
→ app/zabbix.py creates/updates Zabbix hosts via JSON-RPC API
Zabbix SNMP poll (every 1 min)
└── snmpd (net-snmp) → snmp/pass_persist.py reads SQLite, serves OIDs over stdin/stdout
Web UI
└── app/web.py (Flask) → templates/index.html shows player table + activity log
SNMP OID structure — ENTERPRISE_OID.1.1.<column>.<yodeck_id>:
- col 1
STRINGhostname (yodeck-<id>) - col 2
STRINGdisplay name - col 3
INTEGERonline (0/1) - col 4
STRINGlast_seen (ISO-8601) - col 5
INTEGERupdating (0/1) - col 6
INTEGERregistered (0/1)
The Yodeck ID is used directly as the SNMP table index — OIDs are stable (e.g. .1.3.6.1.4.1.99999.1.1.3.54239 = online status of player 54239).
Database — two tables in yodmon.db:
players— one row per Yodeck player, upserted on each polllogs— append-only activity log; event types:yodeck_fetch,zabbix_sync,snmp_transfer,error
Docker entrypoint (entrypoint.sh) templates /etc/snmp/snmpd.conf from env vars at startup, then starts snmpd in the background before handing off to python main.py.
Zabbix integration details
Targets Zabbix 7.x (also works with 6.0+). Each player becomes a host:
- Host name:
yodeck-<id>(e.g.yodeck-54239) —#is not valid in Zabbix 7.x host names - Visible name:
QRS-<yodeck_name>(e.g.QRS-AMS-COF1) - SNMP interface:
APP_HOST:161, SNMPv2c, community fromZABBIX_SNMP_COMMUNITY - Items:
yodeck.online,yodeck.last_seen,yodeck.updating,yodeck.registered— SNMP type 20, polled every 1 minute
Authentication: ZABBIX_API_TOKEN is sent as Authorization: Bearer <token> HTTP header (Zabbix 6.4+ style). If not set, falls back to user.login with ZABBIX_USER/ZABBIX_PASSWORD.
Required Zabbix setup before first run:
- Create host group
Yodeck Playersmanually in Zabbix - Grant the API token's user group Read-write permission on that group (Administration → User groups → Permissions)
- The API token user needs at minimum Zabbix Admin role to create hosts and items