Skip to content

banshee-data/velocity.report

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

velocity.report

A privacy-focused traffic logging tool for neighborhood change-makers.

Measure vehicle speeds, make streets safer.

join-us-on-discord

                                                β–‘β–‘β–‘β–‘
                                               β–’β–“β–ˆβ–ˆβ–ˆβ–“β–“β–“β–“β–’
                                                      β–’β–“β–’β–’
                    β–‘β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–‘                    β–‘β–“β–’β–’
                    β–’β–“β–“β–“β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–‘                β–’β–“β–ˆβ–ˆβ–“β–’
                      β–’β–’β–“β–’β–“β–“β–‘                      β–’β–“β–’β–‘
                         β–‘β–“β–“β–‘                       β–“β–’β–’
                          β–‘β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘
                          β–“β–“β–ˆβ–“β–’β–’β–’β–’β–’β–’β–‘β–‘β–‘β–‘            β–‘β–“β–“β–’
                        β–‘β–“β–“β–’β–“β–“β–‘                   β–‘β–’β–“β–“β–“β–“β–‘
           β–‘β–‘β–’β–’β–’β–’β–‘     β–‘β–“β–’β–‘ β–’β–“β–’                  β–’β–“β–“β–’ β–“β–“β–’ β–‘β–’β–’β–“β–“β–’β–’β–‘
        β–’β–“β–“β–“β–ˆβ–ˆβ–“β–“β–“β–ˆβ–ˆβ–“β–“β–“β–“β–“β–’   β–‘β–“β–“β–‘               β–’β–“β–“β–’   β–’β–ˆβ–ˆβ–“β–“β–ˆβ–“β–“β–“β–“β–“β–“β–’β–“β–“β–’β–‘
     β–‘β–“β–“β–“β–“β–“β–’β–‘ β–‘    β–’β–’β–ˆβ–ˆβ–“β–’β–’   β–’β–“β–’β–‘            β–‘β–“β–“β–’   β–“β–“β–ˆβ–“β–ˆβ–“    β–‘β–‘   β–’β–’β–“β–’β–“β–’
    β–’β–“β–“β–“β–“β–‘    β–‘β–‘   β–‘β–“β–“β–‘β–’β–“β–“β–’   β–’β–“β–’           β–“β–“β–“   β–‘β–“β–“β–“β–‘β–‘β–“β–“β–‘   β–‘β–‘      β–’β–ˆβ–“β–’β–’
  β–‘β–’β–ˆβ–’β–“β–‘β–’     β–‘β–‘  β–‘β–“β–’β–‘  β–‘β–“β–“β–’β–‘ β–‘β–“β–“ β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–“  β–’β–ˆβ–“β–‘   β–’β–“β–ˆβ–’   β–‘β–“β–“β–‘  β–‘β–‘     β–’β–‘β–‘β–’β–ˆβ–“β–’
  β–’β–“β–’β–“   β–’β–‘   β–‘β–‘ β–’β–“β–“     β–‘β–“β–“β–“β–‘ β–‘β–“β–’ β–‘β–“β–’  β–‘β–“β–“β–’    β–’β–“β–ˆβ–’β–‘β–’   β–’β–ˆβ–’  β–‘    β–’β–‘   β–‘β–’β–“β–“β–’
 β–‘β–“β–ˆβ–“     β–‘β–’β–‘ β–‘β–‘β–’β–“β–’       β–‘β–“β–“β–’β–‘β–’β–“β–ˆβ–ˆβ–ˆβ–ˆβ–’ β–’β–“β–“β–‘    β–’β–“β–“β–’    β–’β–’ β–“β–“β–’ β–‘  β–‘β–’      β–‘β–“β–“β–’β–‘
 β–’β–“β–“β–’       β–‘β–’β–’β–“β–ˆβ–“β–“β–“β–ˆβ–ˆβ–ˆβ–“β–“β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–“β–“β–’β–’β–“β–“β–“β–’      β–’β–ˆβ–“β–‘      β–‘β–“β–“β–“β–’β–’β–’β–’         β–’β–“β–’β–’
 β–’β–“β–“β–’β–‘β–‘β–’β–’β–’β–“β–’β–’β–“β–“β–ˆβ–ˆβ–“β–’β–’β–‘β–’β–‘β–‘β–‘  β–’β–“β–’β–’β–“β–“β–“β–“β–“β–ˆβ–“β–“β–“β–‘      β–’β–ˆβ–“β–‘      β–‘β–‘β–‘β–’β–ˆβ–“β–“β–’β–’β–’β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–ˆβ–“β–‘
 β–’β–“β–“β–’       β–‘β–’β–’β–“β–’β–‘         β–“β–“β–“β–‘β–’β–“β–“β–“β–“β–“β–’β–’β–“β–‘      β–’β–“β–“β–’β–’β–‘β–‘β–‘β–‘β–‘   β–‘β–’β–“β–‘β–’β–‘        β–“β–“β–“β–‘
 β–‘β–“β–ˆβ–“β–‘    β–‘β–’β–‘ β–‘β–’  β–’β–‘      β–’β–“β–“β–’  β–’β–ˆβ–ˆβ–ˆβ–“β–“β–“β–‘       β–‘β–“β–“β–’       β–‘β–‘  β–‘  β–‘β–’β–‘     β–‘β–“β–“β–“β–‘
  β–’β–“β–“β–“β–‘  β–’β–‘    β–’    β–’β–‘   β–‘β–“β–“β–“β–‘    β–’β–“            β–“β–“β–“β–‘     β–’    β–‘β–‘   β–‘β–’β–‘  β–‘β–“β–ˆβ–“β–‘
   β–’β–“β–“β–“β–’β–‘     β–‘β–’     β–‘β–’ β–’β–“β–“β–’     β–‘β–“β–’            β–‘β–’β–“β–“β–‘  β–‘β–‘     β–‘β–‘      β–’β–’β–“β–“β–“β–‘
    β–’β–“β–“β–“β–’β–‘     β–’      β–‘β–“β–“β–“β–’     β–“β–ˆβ–“β–“β–ˆβ–‘            β–’β–“β–“β–“β–’β–‘      β–’β–‘     β–‘β–“β–ˆβ–“β–“β–‘
     β–‘β–’β–“β–ˆβ–ˆβ–“β–’β–’  β–’  β–‘β–’β–“β–“β–ˆβ–“β–’β–‘                         β–‘β–“β–“β–ˆβ–“β–“β–‘    β–‘β–‘ β–‘β–’β–“β–ˆβ–“β–“β–“β–‘
      β–‘β–‘β–‘β–’β–’β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–“β–“β–‘                β–‘β–‘             β–’β–“β–“β–“β–“β–ˆβ–ˆβ–“β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–’β–‘
  β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–’β–’β–’β–’β–“β–’β–’β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘
      β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘  β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘
   β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘
     β–‘β–‘β–‘    β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘ β–‘β–‘β–‘β–‘    β–‘β–‘β–‘    β–‘β–‘β–‘β–‘    β–‘β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘β–‘   β–‘β–‘β–‘β–‘β–‘

Overview

velocity.report is a complete citizen radar system for neighborhood traffic monitoring. The system consists of three main components:

  • Go Server - High-performance data collection and API server
  • Python PDF Generator - Professional PDF report generation with LaTeX
  • Web Frontend - Real-time data visualization (Svelte)

The system collects vehicle speed data from radar/LIDAR sensors, stores it in SQLite, and provides multiple ways to visualize and report on the dataβ€”all while maintaining complete privacy (no license plate recognition, no video recording).

Quick Start

For Go Server Development

git clone git@github.com:banshee-data/velocity.report.git
cd velocity.report
make build-radar-local
./velocity-report-local --disable-radar

If an existing SQLite database is available, place it in ./sensor_data.db (the default location for development). For production deployments, use the --db-path flag to specify a different location (see Deployment section).

For PDF Report Generation

See tools/pdf-generator/README.md for detailed instructions.

Quick version:

cd tools/pdf-generator
make install-python         # One-time setup
make pdf-config             # Create config template
make pdf-report CONFIG=config.json

For Web Frontend Development

See web/README.md for detailed instructions.

Project Structure

velocity.report/
β”œβ”€β”€ cmd/                      # Go CLI applications
β”‚   β”œβ”€β”€ radar/                # Radar sensor integration
β”‚   β”œβ”€β”€ bg-sweep/             # Background sweep utilities
β”‚   └── tools/                # Go utility tools
β”œβ”€β”€ internal/                 # Go server internals (private packages)
β”‚   β”œβ”€β”€ api/                  # HTTP API endpoints
β”‚   β”œβ”€β”€ db/                   # SQLite database layer
β”‚   β”œβ”€β”€ radar/                # Radar sensor logic
β”‚   β”œβ”€β”€ lidar/                # LIDAR sensor logic
β”‚   β”œβ”€β”€ monitoring/           # System monitoring
β”‚   └── units/                # Unit conversion utilities
β”œβ”€β”€ web/                      # Svelte web frontend
β”‚   β”œβ”€β”€ src/                  # Frontend source code
β”‚   └── static/               # Static assets
β”œβ”€β”€ tools/                    # Python tooling
β”‚   └── pdf-generator/        # PDF report generation
β”‚       β”œβ”€β”€ pdf_generator/    # Python package
β”‚       β”‚   β”œβ”€β”€ cli/          # CLI tools
β”‚       β”‚   β”œβ”€β”€ core/         # Core modules
β”‚       β”‚   └── tests/        # Test suite
β”‚       └── output/           # Generated PDFs
β”œβ”€β”€ data/                     # Data directory
β”‚   β”œβ”€β”€ migrations/           # Database migrations
β”‚   └── align/                # Data alignment utilities
β”œβ”€β”€ docs/                     # Documentation Site
β”œβ”€β”€ scripts/                  # Development shell scripts
└── static/                   # Static server assets

Architecture

Data Flow

   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚     Sensors       │────►│     Go Server     │◄───►│  SQLite Database  β”‚
   β”‚ (Radar / LIDAR)   β”‚     β”‚ (API/Processing)  β”‚     β”‚ (Time-series)     β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                     β”‚
                                     β”‚
                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚                                   β”‚
                   β–Ό                                   β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚        Web Frontend         β”‚     β”‚    Python PDF Generator     β”‚
   β”‚   (Real-time via Svelte)    β”‚     β”‚ (Offline Reports via LaTeX) β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Components

1. Go Server (/cmd/, /internal/)

  • Collects data from radar/LIDAR sensors
  • Stores time-series data in SQLite
  • Provides HTTP API for data access
  • Handles background processing tasks
  • Runs as systemd service on Raspberry Pi

2. Python PDF Generator (/tools/pdf-generator/)

  • Generates professional PDF reports using LaTeX
  • Creates charts and visualizations with matplotlib
  • Processes statistical summaries
  • Highly configurable via JSON
  • Comprehensive test suite

3. Web Frontend (/web/)

  • Real-time data visualization
  • Interactive charts and graphs
  • Built with Svelte and TypeScript
  • Responsive design

See ARCHITECTURE.md for detailed architecture documentation.

Development

Prerequisites

For Go Development:

For Python PDF Generation:

For Web Frontend:

Go Server Development

Build the development server:

make build-radar-local
./velocity-report-local --disable-radar

Run tests:

make test

Build for production (Raspberry Pi):

make build-radar-linux
# or manually:
GOOS=linux GOARCH=arm64 go build -o velocity-report-linux-arm64 ./cmd/radar

Python PDF Generator Development

The repository uses a single shared Python virtual environment for all Python tools (PDF generator, data visualization, analysis scripts).

Setup:

make install-python  # Creates .venv and installs all dependencies

Activate manually (optional):

source .venv/bin/activate

What's installed:

  • PDF generation: PyLaTeX, reportlab
  • Data analysis: pandas, numpy, scipy
  • Visualization: matplotlib, seaborn
  • Testing: pytest, pytest-cov
  • Formatting: black, ruff

Run PDF Generator:

make pdf-test         # Run test suite
make pdf-demo         # Run interactive demo
make pdf-config       # Create config template
make pdf-report CONFIG=config.json  # Generate PDF report

Code Formatting

Option 1: Format on demand (recommended for new contributors)

make format        # Format all code before commit
make lint          # Verify formatting (what CI checks)

Option 2: Editor integration

  • VS Code: Install Prettier, ESLint, Go extensions
  • Format-on-save handles most cases

Option 3: Pre-commit hooks (recommended for regular contributors)

pip install pre-commit
pre-commit install

Hooks auto-format code on every commit β€” no manual make format needed.

What runs on commit (if hooks enabled):

  • File hygiene (trailing whitespace, large files, etc.)
  • Go formatting (gofmt)
  • Python formatting (ruff + black) for PDF generator code
  • Web formatting (prettier)

Note: CI lint jobs are advisory (non-blocking), so PRs can merge even without perfect formatting. A weekly automated workflow cleans up any missed formatting issues. See .github/workflows/lint-autofix.yml for details.

Web Frontend Development

cd web
pnpm install
pnpm dev

See web/README.md for details.

Deployment

Go Server (Raspberry Pi)

The Go server runs as a systemd service on Raspberry Pi. Use the new velocity-deploy tool for comprehensive deployment management.

Quick Start - Deploy to Raspberry Pi:

# Build the binary and deployment tool
make build-radar-linux
make build-deploy

# Deploy to remote Pi
./velocity-deploy install \
  --target pi@192.168.1.100 \
  --ssh-key ~/.ssh/id_rsa \
  --binary ./velocity-report-linux-arm64

Or use Make shortcuts for local deployment:

make build-radar-linux
make deploy-install

The deployment will:

  • Install the binary to /usr/local/bin/velocity-report
  • Create a dedicated service user and working directory
  • Install and enable the systemd service
  • Optionally migrate existing database

Upgrade to new version:

make build-radar-linux
./velocity-deploy upgrade --target pi@192.168.1.100 --binary ./velocity-report-linux-arm64

Monitor service health:

# Comprehensive health check
./velocity-deploy health --target pi@192.168.1.100

# Check status
./velocity-deploy status --target pi@192.168.1.100

# View logs
sudo journalctl -u velocity-report.service -f

See also:

Legacy deployment:

The previous scripts/setup-radar-host.sh script is still available but the new velocity-deploy tool is recommended for all deployments.

Python PDF Generator

The PDF generator is deployed as a Python package via PYTHONPATH:

cd tools/pdf-generator
make install-python
# PDF generator is now ready at tools/pdf-generator/pdf_generator/

No installation required - use PYTHONPATH method as documented in tools/pdf-generator/README.md.

Documentation

Testing

Go Tests

make test

Python Tests (PDF Generator)

cd tools/pdf-generator
make pdf-test
# or with coverage:
make test-python-cov

Make Targets

The project uses a consistent naming scheme for all make targets: <action>-<subsystem>[-<variant>]

Core Subsystem Targets

Action Go Python Web Docs
install - install-python install-web install-docs
dev dev-go - dev-web dev-docs
dev (variant) dev-go-lidar
dev-go-kill-server
- - -
test test-go test-python test-web -
test (variant) - test-python-cov - -
format format-go format-python format-web -
lint lint-go lint-python lint-web -
clean - clean-python - -

Aggregate Targets

  • test - Run all tests (Go + Python + Web)
  • format - Format all code (Go + Python + Web)
  • lint - Lint all code (Go + Python + Web), fails if formatting needed

Build Targets (Go cross-compilation)

  • build-radar-linux - Build for Linux ARM64 (no pcap)
  • build-radar-linux-pcap - Build for Linux ARM64 with pcap
  • build-radar-mac - Build for macOS ARM64 with pcap
  • build-radar-mac-intel - Build for macOS AMD64 with pcap
  • build-radar-local - Build for local development with pcap
  • build-tools - Build sweep tool
  • build-web - Build web frontend (SvelteKit)
  • build-docs - Build documentation site (Eleventy)

Deployment Targets

  • setup-radar - Install server on this host (requires sudo)

PDF Generator Targets

  • pdf-report - Generate PDF from config file
  • pdf-config - Create example configuration
  • pdf-demo - Run configuration demo
  • pdf-test - Run PDF tests (alias for test-python)
  • pdf - Convenience alias for pdf-report

Utility Targets

  • log-go-tail - Tail most recent Go server log
  • log-go-cat - Cat most recent Go server log

Data Visualization Targets

  • plot-noise-sweep - Generate noise sweep line plot
  • plot-multisweep - Generate multi-parameter grid plot
  • plot-noise-buckets - Generate per-noise bar charts
  • stats-live - Capture live LiDAR grid snapshots
  • stats-pcap - Capture snapshots during PCAP replay

API Shortcut Targets (LiDAR HTTP API)

Grid operations: api-grid-status, api-grid-reset, api-grid-heatmap Snapshots: api-snapshot, api-snapshots Acceptance metrics: api-acceptance, api-acceptance-reset Parameters: api-params, api-params-set Export: api-persist, api-export-snapshot, api-export-next-frame Status & PCAP: api-status, api-start-pcap, api-stop-pcap, api-switch-data-source

Run make help or make to see all available targets with descriptions.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for:

  • Development workflow (Go + Python + Web)
  • Testing requirements
  • Code style guidelines
  • Pull request process

License

Apache License 2.0 - See LICENSE for details.

Community

join-us-on-discord

Join our Discord community to discuss the project, get help, and contribute to making streets safer.

Privacy & Ethics

This project is designed with privacy as a core principle:

  • βœ… No license plate recognition
  • βœ… No video recording
  • βœ… No personally identifiable information

The goal is to empower communities to make data-driven decisions about street safety without compromising individual privacy.