{"id":51858592,"url":"https://github.com/stuttgart-things/homerun2-led-catcher","last_synced_at":"2026-07-24T03:31:08.977Z","repository":{"id":345012683,"uuid":"1183910584","full_name":"stuttgart-things/homerun2-led-catcher","owner":"stuttgart-things","description":"RGB LED matrix catcher for homerun2 - consumes Redis Streams messages and displays on LED matrix hardware with embedded HTMX simulator","archived":false,"fork":false,"pushed_at":"2026-04-15T15:08:19.000Z","size":90,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T15:24:11.818Z","etag":null,"topics":["homerun2","iot","led-matrix","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stuttgart-things.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-17T04:09:40.000Z","updated_at":"2026-04-15T13:50:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/stuttgart-things/homerun2-led-catcher","commit_stats":null,"previous_names":["stuttgart-things/homerun2-led-catcher"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/stuttgart-things/homerun2-led-catcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fhomerun2-led-catcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fhomerun2-led-catcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fhomerun2-led-catcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fhomerun2-led-catcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stuttgart-things","download_url":"https://codeload.github.com/stuttgart-things/homerun2-led-catcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fhomerun2-led-catcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35826032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-24T02:00:07.870Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["homerun2","iot","led-matrix","python"],"created_at":"2026-07-24T03:31:07.749Z","updated_at":"2026-07-24T03:31:08.951Z","avatar_url":"https://github.com/stuttgart-things.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# homerun2-led-catcher\n\nRGB LED matrix catcher for the [homerun2](https://github.com/stuttgart-things) ecosystem — consumes messages from Redis Streams and displays them on a 64x64 RGB LED matrix with an embedded HTMX web simulator.\n\n## Architecture\n\n```\nRedis Streams → RedisConsumer → log_handler (structured JSON logging)\n                              → led_handler (64x64 RGB LED matrix via rpi-rgb-led-matrix)\n                              → web_handler (HTMX browser simulator)\n```\n\n| Mode | Description |\n|------|-------------|\n| `led` | Hardware LED matrix only (Raspberry Pi) |\n| `web` | HTMX simulator only (browser, no hardware needed) |\n| `full` | Both LED matrix and web simulator |\n\n## Quick Start (Development)\n\n```bash\n# Clone\ngit clone https://github.com/stuttgart-things/homerun2-led-catcher.git\ncd homerun2-led-catcher\n\n# Install\npip install -e \".[dev]\"\n\n# Run in web-only mode (no Raspberry Pi needed)\nLED_MODE=web LOG_FORMAT=text REDIS_ADDR=localhost python -m led_catcher\n```\n\nThe health endpoint is available at `http://localhost:8080/healthz`.\n\n## Raspberry Pi Hardware Setup\n\n### Requirements\n\n- Raspberry Pi (3B+ or newer recommended)\n- 64x64 RGB LED Matrix panel\n- Adafruit RGB Matrix HAT or Bonnet\n- Raspberry Pi OS (Legacy) Lite — Debian Bullseye, 32-bit\n- Python 3.11+\n\n### Build rpi-rgb-led-matrix\n\n```bash\ngit clone https://github.com/hzeller/rpi-rgb-led-matrix.git\ncd rpi-rgb-led-matrix\n\n# Configure for Adafruit HAT with PWM\nsed -i 's/^HARDWARE_DESC?=regular/#HARDWARE_DESC?=regular/; s/^#HARDWARE_DESC=adafruit-hat-pwm/HARDWARE_DESC=adafruit-hat-pwm/' lib/Makefile\n\n# Build and install Python bindings\ncd bindings/python\nmake build-python \u0026\u0026 sudo make install-python\n```\n\n### Disable audio driver (interferes with LED matrix)\n\n```bash\necho \"snd_bcm2835\" | sudo tee /etc/modprobe.d/blacklist-rgb-matrix.conf\nsudo update-initramfs -u\nsudo reboot\n```\n\n### Run on Pi\n\n```bash\npip install .\n\n# With hardware LED matrix\nsudo LED_MODE=led REDIS_ADDR=\u003credis-host\u003e PROFILE_PATH=profile.yaml python -m led_catcher\n\n# With hardware + web simulator\nsudo LED_MODE=full REDIS_ADDR=\u003credis-host\u003e PROFILE_PATH=profile.yaml python -m led_catcher\n```\n\n\u003e **Note:** `sudo` is required for GPIO access on the Raspberry Pi.\n\n## Configuration\n\nAll configuration is via environment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `REDIS_ADDR` | `localhost` | Redis host |\n| `REDIS_PORT` | `6379` | Redis port |\n| `REDIS_PASSWORD` | *(empty)* | Redis password |\n| `REDIS_STREAM` | `messages` | Redis stream to consume |\n| `CONSUMER_GROUP` | `homerun2-led-catcher` | Consumer group name |\n| `CONSUMER_NAME` | hostname | Consumer name within group |\n| `LED_MODE` | `full` | Operating mode: `led`, `web`, `full` |\n| `HEALTH_PORT` | `8080` | Health/web server port |\n| `PROFILE_PATH` | `profile.yaml` | Path to display rules YAML |\n| `LOG_FORMAT` | `json` | Log format: `json` or `text` |\n| `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warning`, `error` |\n\n## Display Profile\n\nDisplay rules are defined in a YAML profile that maps (system, severity) to display modes:\n\n```yaml\ndisplayRules:\n  github-error:\n    systems: [github, gitlab]\n    severity: [ERROR]\n    kind: gif\n    image: sunset.gif\n    duration: 5\n\n  scale-weight:\n    systems: [scale]\n    severity: [INFO]\n    kind: static\n    text: \"{{ message | replace('WEIGHT: ','') }}g\"\n    font: myfont.bdf\n    duration: 3\n\n  default-info:\n    systems: [\"*\"]\n    severity: [INFO, SUCCESS]\n    kind: text\n    text: \"{{ system }}: {{ title }}\"\n    font: myfont.bdf\n    duration: 5\n\ncolors:\n  error: [255, 0, 0]\n  warning: [255, 165, 0]\n  success: [0, 255, 0]\n  info: [0, 100, 255]\n```\n\n## Docker\n\n```bash\n# Build\ndocker build -t homerun2-led-catcher:local .\n\n# Run (web mode)\ndocker run -p 8080:8080 \\\n  -e LED_MODE=web \\\n  -e REDIS_ADDR=host.docker.internal \\\n  homerun2-led-catcher:local\n```\n\n## Kubernetes (KCL)\n\n```bash\n# Render manifests\nkcl run kcl/ -D config.image=ghcr.io/stuttgart-things/homerun2-led-catcher:latest \\\n             -D config.namespace=homerun2 \\\n             -D config.redisAddr=redis-stack.homerun2.svc.cluster.local\n\n# Or use a deploy profile\nkcl run kcl/ -y tests/kcl-deploy-profile.yaml\n```\n\n## Development\n\n```bash\n# Install with dev dependencies\npip install -e \".[dev]\"\n\n# Install pre-commit hook (runs before every git commit)\ntask setup-precommit\n```\n\n### Pre-commit Hook\n\nA git pre-commit hook ensures code quality before every commit. It runs:\n\n1. `ruff check` — linting\n2. `ruff format --check` — formatting validation\n3. `pytest` — 28 unit tests\n\nCommits are blocked if any check fails. Run manually with `task precommit`.\n\n### Task Commands\n\n```bash\n# Local checks (fast, no Docker/Dagger needed)\ntask precommit         # lint + format-check + test (same as pre-commit hook)\ntask lint              # ruff check\ntask format            # ruff format (auto-fix)\ntask format-check      # ruff format --check\ntask test              # pytest\n\n# Stage 1: Push — validation via Dagger (same as GH Actions on push)\ntask ci                # lint + format-check + test + security-scan\n\n# Stage 2: PR — full verification (same as GH Actions on PR)\ntask ci-pr             # Stage 1 + docker build → ttl.sh → trivy scan\n\n# Stage 3: Release — full release (same as GH Actions release)\ntask ci-release        # Stage 2 + kustomize OCI push\n\n# Individual Dagger tasks\ntask ci-lint           # ruff via dagger\ntask ci-format-check   # ruff format via dagger\ntask ci-test           # pytest via dagger\ntask ci-security-scan  # bandit via dagger\ntask ci-docker-build   # docker build via dagger\ntask ci-docker-push    # build + push to ttl.sh\ntask ci-trivy-scan     # trivy scan image on ttl.sh\ntask ci-push-kustomize # KCL → kustomize OCI to ttl.sh\n\n# Other\ntask run               # LED_MODE=web, no hardware needed\ntask build-image       # docker build locally\ntask pages-local       # build mkdocs locally\n```\n\n### CI/CD Pipeline\n\nEvery stage runs the same Dagger modules locally (`task`) and in GitHub Actions:\n\n```\nPre-commit (git hook)\n│  ruff check + ruff format --check + pytest\n│\n├─► Push to branch (Stage 1: build-test.yaml)\n│     Lint, Format-Check, Test, Security-Scan\n│     Local: task ci\n│\n├─► Pull Request (Stage 2: build-scan-image.yaml + push-kustomize-pr.yaml)\n│     Docker build → push GHCR `pr-\u003cnum\u003e-\u003csha\u003e` → Trivy scan\n│     Kustomize OCI → push GHCR `\u003crepo\u003e-kustomize:pr-\u003cnum\u003e-\u003csha\u003e`\n│     ArgoCD AppSet spins up a preview env at\n│     `led-pr-\u003cnum\u003e.homerun2-dev.sthings-vsphere.labul.sva.de`\n│     (add the `preview` label to the PR to opt in)\n│     Local: task ci-pr\n│\n├─► Merge to main (Stage 3: release.yaml)\n│     Semantic release → Docker push GHCR → KCL kustomize OCI push\n│     Local: task ci-release\n│\n└─► After release (pages.yaml)\n      mkdocs-material → GitHub Pages\n      Local: task pages-local\n```\n\nAll CI uses reusable Dagger modules from [`stuttgart-things/dagger`](https://github.com/stuttgart-things/dagger):\n\n| Module | Functions |\n|--------|-----------|\n| `python` | lint, format-check, test, security-scan, build-image |\n| `docker` | build, push |\n| `trivy` | scan-image |\n| `kcl` | push-kustomize-base |\n| `release` | semantic |\n\n## Related Projects\n\n| Project | Description |\n|---------|-------------|\n| [homerun2-omni-pitcher](https://github.com/stuttgart-things/homerun2-omni-pitcher) | HTTP producer — sends messages to Redis Streams |\n| [homerun2-core-catcher](https://github.com/stuttgart-things/homerun2-core-catcher) | Core consumer — log/CLI/web display modes |\n| [homerun2-light-catcher](https://github.com/stuttgart-things/homerun2-light-catcher) | WLED light consumer — triggers LED strip effects |\n| [homerun2-git-pitcher](https://github.com/stuttgart-things/homerun2-git-pitcher) | GitHub watcher — polls GitHub API for events and pitches them to Redis Streams |\n| [homerun2-notification-catcher](https://github.com/stuttgart-things/homerun2-notification-catcher) | Notification consumer — routes messages to MS Teams / webhooks via YAML-configured filters |\n| [homerun-library](https://github.com/stuttgart-things/homerun-library) | Shared Go library for message types and Redis ops |\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuttgart-things%2Fhomerun2-led-catcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstuttgart-things%2Fhomerun2-led-catcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuttgart-things%2Fhomerun2-led-catcher/lists"}