Skip to content

aktnk/weather-warning-checker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tauri Weather Checker

Rust + Tauri implementation of the JMA Weather Warning Checker.

Project Status

PRODUCTION READY

All features have been implemented and tested. This application is feature-complete and production-ready.

Features

  • Database layer (SQLite with sqlx, async)
  • Configuration management (environment variables, .env support)
  • Email notifications (Gmail SMTP with rustls)
  • Scheduler (10-minute weather checks, daily cleanup at 01:00)
  • Error handling (custom error types with thiserror)
  • Data cleanup (old records removal, soft delete, XML file movement)
  • JMA XML Parser - Complete implementation:
    • extra.xml parsing (Atom feed, If-Modified-Since)
    • VPWW54 format parsing (full-width character support)
    • City-level warning extraction
    • "No warnings" status handling (発表警報・注意報はなし)
  • Weather Checker - Complete implementation:
    • Status change detection
    • XML file change detection (updates DB without notification)
    • Database integration
    • Notification triggering
    • LMO cleanup when no entry in extra.xml
  • Resilience - Two-layer architecture (code-level + OS-level):
    • Enhanced logging (elapsed time, consecutive failure counter)
    • Heartbeat file for external monitoring
    • Startup notification email
    • Graceful shutdown (SIGTERM/SIGINT handling)
    • Crash recovery with OS-level auto-restart
  • Deployment - Service configurations for multiple platforms:
    • systemd (Ubuntu), launchd (macOS), NSSM (Windows)

Architecture

This is a background service application that runs continuously:

Tauri App (Background Service)
├── Scheduler (tokio-cron-scheduler)
│   ├── Weather check: Every 10 minutes
│   ├── Cleanup: Daily at 01:00
│   ├── Heartbeat file (data/heartbeat)
│   └── Startup notification email
├── Database (SQLite via sqlx)
│   ├── Extra (Last-Modified tracking)
│   ├── VPWW54xml (XML file cache)
│   └── CityReport (Warning state)
├── JMA Feed Client
│   ├── Fetch extra.xml with If-Modified-Since
│   ├── Parse VPWW54 entries
│   ├── Download and cache warning data
│   └── Handle "no warnings" status
├── Weather Checker
│   ├── Compare and detect changes
│   ├── Track XML file changes
│   └── Clean up old data
├── Notification (Gmail SMTP)
│   ├── Send email on warning status change
│   └── Send system notification (startup, etc.)
└── Resilience
    ├── Graceful shutdown (SIGTERM/SIGINT via CancellationToken)
    ├── Crash recovery monitor (exit(1) for OS-level restart)
    └── Enhanced logging (elapsed time, failure counter)

Prerequisites

  • Rust 1.70+ (tested with 1.91.1)
  • System dependencies (for Tauri):
    • Linux: libwebkit2gtk-4.1-dev, build-essential, curl, wget, file, libssl-dev, libgtk-3-dev, librsvg2-dev
    • macOS: Xcode Command Line Tools
    • Windows: Microsoft Visual Studio C++ Build Tools

Quick Start

1. Install System Dependencies (Ubuntu/Debian)

sudo apt update
sudo apt install libwebkit2gtk-4.1-dev \
  build-essential \
  curl \
  wget \
  file \
  libssl-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev

2. Create Environment File

cp .env.example .env
# Edit .env and add your Gmail credentials

Required environment variables:

GMAIL_APP_PASS=your_gmail_app_password
GMAIL_FROM=your_email@gmail.com
EMAIL_TO=recipient@example.com
EMAIL_BCC=bcc@example.com  # Optional

3. Build and Run

Development mode (with debug logs):

cd src-tauri
RUST_LOG=tauri_weather_checker=debug cargo run

Production mode:

cd src-tauri
cargo build --release
./target/release/tauri-weather-checker

Running the Application

Development Mode (Recommended for Testing)

cd src-tauri

# With detailed logging
RUST_LOG=tauri_weather_checker=debug cargo run

# With standard logging
cargo run

What happens:

  1. Initializes SQLite database
  2. Runs initial weather check
  3. Schedules checks every 10 minutes
  4. Schedules cleanup daily at 01:00
  5. Continues running indefinitely

Stop with: Ctrl+C

Production Mode

cd src-tauri

# Build release binary (first time only)
cargo build --release

# Run the binary
./target/release/tauri-weather-checker

# Or with logging
RUST_LOG=tauri_weather_checker=info ./target/release/tauri-weather-checker

Deployment as a Service

For production use, run as a system service with automatic restart and monitoring. Service configuration files for systemd (Ubuntu), launchd (macOS), and NSSM (Windows) are provided in the deploy/ directory.

See deploy/README.md for detailed setup instructions.

Configuration

All configuration is done via environment variables (.env file):

Variable Description Default Required
CONFIG_PATH Path to config.yaml config.yaml No
DATADIR XML cache directory data/xml No
DELETED_DIR Deleted XML directory data/deleted No
DB_PATH SQLite database path data/weather.sqlite3 No
GMAIL_APP_PASS Gmail app password - Yes
GMAIL_FROM Sender email - Yes
EMAIL_TO Recipient email - Yes
EMAIL_BCC BCC email (comment out to disable) - No

Gmail Setup

  1. Enable 2-factor authentication in Google Account
  2. Generate an app password: https://myaccount.google.com/apppasswords
  3. Use the app password (not your regular password) in GMAIL_APP_PASS

Monitoring Regions

Monitored regions are configured in config.yaml:

monitored_regions:
  - lmo: "静岡地方気象台"
    cities:
      - name: "裾野市"
        url: "https://www.jma.go.jp/bosai/warning/#lang=ja&area_type=class20s&area_code=2222000"
      - name: "御殿場市"
        url: "https://www.jma.go.jp/bosai/warning/#lang=ja&area_type=class20s&area_code=2221500"
  - lmo: "金沢地方気象台"
    cities:
      - name: "能登町"

Each city entry has the following fields:

Field Description Required
name City name as it appears in JMA warnings Yes
url JMA warning page URL for this city No

url is optional. If omitted, the notification email will link to the JMA national warnings page (https://www.jma.go.jp/bosai/warning/). The city-specific URL can be found at JMA Warning Page by navigating to the target city and copying the URL from the browser address bar.

Set the config file path in .env:

CONFIG_PATH=../config.yaml

After modifying config.yaml, changes take effect on the next 10-minute check cycle (no restart or rebuild required).

Project Structure

weather-warning-checker/
├── src-tauri/
│   ├── src/
│   │   ├── main.rs           # Entry point, Tauri setup
│   │   ├── config.rs         # Environment and YAML configuration
│   │   ├── database.rs       # SQLite operations
│   │   ├── jma_feed.rs       # JMA XML fetching/parsing
│   │   ├── weather_checker.rs # Core warning logic
│   │   ├── notification.rs   # Email notifications (test mode support)
│   │   ├── cleanup.rs        # Data cleanup tasks
│   │   ├── scheduler.rs      # Cron-like scheduling
│   │   └── error.rs          # Error types
│   ├── Cargo.toml            # Rust dependencies
│   ├── tauri.conf.json       # Tauri configuration
│   └── data/                 # Auto-created (runtime data)
│       ├── xml/              # XML cache
│       ├── deleted/          # Deleted XML files
│       └── weather.sqlite3   # Database
├── deploy/
│   ├── systemd/              # Ubuntu service files
│   │   ├── weather-checker.service
│   │   ├── weather-checker-watchdog.service
│   │   └── weather-checker-watchdog.timer
│   ├── launchd/              # macOS plist
│   │   └── com.aktnk.weather-checker.plist
│   ├── windows/              # Windows NSSM scripts
│   │   ├── install.ps1
│   │   └── uninstall.ps1
│   └── README.md             # Deployment guide
├── config.yaml               # Monitored regions configuration
├── .env                      # Environment configuration
├── .env.example              # Example environment file
└── README.md                 # This file

Database

The application uses SQLite with the following tables:

  • extra: Tracks Last-Modified header from JMA
  • vpww54xml: Records all downloaded XML files
  • city_report: Tracks current warning status for each city+warning combination

Database location: data/weather.sqlite3

To inspect:

sqlite3 data/weather.sqlite3
.tables
SELECT * FROM city_report WHERE is_delete = 0;
.quit

Logging

Log levels: error, warn, info, debug, trace

# Minimal logs (info and above)
RUST_LOG=tauri_weather_checker=info cargo run

# Debug logs (recommended for development/testing)
# Note: Email subjects are prefixed with "test:" in debug mode
RUST_LOG=tauri_weather_checker=debug cargo run

# All logs (very verbose)
RUST_LOG=tauri_weather_checker=trace cargo run

Test Mode

When RUST_LOG contains "debug", email subjects are automatically prefixed with "test:":

  • Debug mode: test:裾野市:大雨警報:発表
  • Production mode: 裾野市:大雨警報:発表

Troubleshooting

Database Errors

# Delete database to reinitialize
rm -f data/weather.sqlite3
cargo run

Email Not Sending

  • Verify .env file exists with correct credentials
  • Check Gmail app password (not regular password)
  • Ensure 2FA is enabled on Google account
  • Review logs: RUST_LOG=tauri_weather_checker=debug cargo run

Build Errors

# Update Rust
rustup update

# Clean build
cd src-tauri
cargo clean
cargo build

Compilation Errors

# Check Rust version (1.70+ required)
rustc --version

# Update dependencies
cargo update

Contributing

When making changes:

  1. Format code: cargo fmt
  2. Run linter: cargo clippy
  3. Check compilation: cargo check
  4. Test: cargo run
  5. Build release: cargo build --release

Optional Enhancements

Future improvements:

  • System tray menu (icons needed)
  • GUI configuration interface
  • Log file rotation
  • Auto-update mechanism

License

MIT License

About

Regularly check and notify of warnings and advisories issued by the Japan Meteorological Agency

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors