# MeshAI Configuration
# LLM-powered Meshtastic assistant
#
# Copy this to config.yaml and customize as needed
# For Docker: mount as /data/config.yaml

# === BOT IDENTITY ===
bot:
  name: ai                       # Bot's display name
  owner: ""                      # Owner's callsign (optional)
  respond_to_dms: true           # Respond to direct messages
  filter_bbs_protocols: true     # Ignore advBBS sync/notification messages

# === MESHTASTIC CONNECTION ===
connection:
  type: tcp                      # serial | tcp
  serial_port: /dev/ttyUSB0      # For serial connection
  tcp_host: localhost            # For TCP connection (meshtasticd)
  tcp_port: 4403

# === RESPONSE BEHAVIOR ===
response:
  delay_min: 2.2                 # Min delay before responding (seconds)
  delay_max: 3.0                 # Max delay before responding
  max_length: 200                # Max chars per message chunk
  max_messages: 3                # Max message chunks per response

# === CONVERSATION HISTORY ===
history:
  database: /data/conversations.db
  max_messages_per_user: 50      # Messages to keep per user
  conversation_timeout: 86400    # Conversation expiry (seconds, 86400=24h)

# === MEMORY OPTIMIZATION ===
memory:
  enabled: true                  # Enable rolling summary memory
  window_size: 4                 # Recent message pairs to keep in full
  summarize_threshold: 8         # Messages before re-summarizing

# === MESH CONTEXT ===
context:
  enabled: true                  # Observe channel traffic for LLM context
  observe_channels: []           # Channel indices to observe (empty = all)
  ignore_nodes: []               # Node IDs to exclude from observation
  max_age: 1209600               # Max age in seconds (default 14 days)
  max_context_items: 20          # Max observations injected into LLM context

# === LLM BACKEND ===
llm:
  backend: openai                # openai | anthropic | google
  api_key: ${GOOGLE_API_KEY}      # Secret: set via dashboard or /data/secrets/.env (var depends on backend: GOOGLE_API_KEY/OPENAI_API_KEY/ANTHROPIC_API_KEY)
  base_url: https://api.openai.com/v1  # API base URL
  model: gpt-4o-mini             # Model name
  timeout: 30                    # Request timeout (seconds)
  system_prompt: >-
    You are a helpful assistant on a Meshtastic mesh network.
    Keep responses very brief - 1-2 short sentences, under 300 characters.
    Only give longer answers if the user explicitly asks for detail or explanation.
    Be concise but friendly. No markdown formatting.
  google_grounding: false        # Enable Google Search grounding (Gemini only, $35/1k queries)

# === WEATHER ===
weather:
  primary: openmeteo             # openmeteo | wttr | llm
  fallback: llm                  # openmeteo | wttr | llm | none
  default_location: ""           # Default location for !weather (optional)

# === MESHMONITOR INTEGRATION ===
meshmonitor:
  enabled: false                 # Enable MeshMonitor trigger sync
  url: ""                        # MeshMonitor web UI URL (e.g. http://192.168.1.100:3333)
  inject_into_prompt: true       # Include trigger list in LLM prompt
  refresh_interval: 300          # Seconds between trigger refreshes

# === KNOWLEDGE BASE (RAG) ===
knowledge:
  enabled: false                 # Enable knowledge base search
  db_path: ""                    # Path to knowledge SQLite database
  top_k: 5                       # Number of chunks to retrieve per query

# === MESH DATA SOURCES ===
# Connect to Meshview and/or MeshMonitor instances for live mesh
# network analysis. Supports multiple sources. Configure via the
# dashboard (Mesh Sources) or by editing this file directly.
#
# mesh_sources:
#   - name: "my-meshview"
#     type: meshview
#     url: "https://meshview.example.com"
#     refresh_interval: 300
#     enabled: true
#
#   - name: "my-meshmonitor"
#     type: meshmonitor
#     url: "http://192.168.1.100:3333"
#     api_token: "${MM_API_TOKEN}"
#     refresh_interval: 300
#     enabled: true
#
#   - name: "mqtt-broker"
#     type: mqtt
#     host: "mqtt.meshtastic.org"
#     port: 1883
#     username: "meshdev"
#     password: "large4cats"
#     topic_root: "msh/US"
#     use_tls: false
#     enabled: true
mesh_sources: []

# === MESH INTELLIGENCE ===
# Geographic clustering and health scoring for mesh analysis.
# Requires mesh_sources to be configured with at least one data source.
#
# mesh_intelligence:
#   enabled: true
#   regions:                        # Fixed region anchors (explicit, not auto-clustered)
#     - name: "magic_valley"
#       lat: 42.56
#       lon: -114.47
#       local_name: "Magic Valley"
#       description: "Twin Falls, Burley, Jerome along I-84/US-93"
#       aliases: ["southern Idaho"]
#       cities: ["Twin Falls", "Burley", "Jerome"]
#   locality_radius_miles: 8.0      # Radius for locality clustering within regions
#   offline_threshold_hours: 2      # Hours before node considered offline
#   packet_threshold: 500           # Non-text packets per 24h to flag
#   battery_warning_percent: 30     # Battery level for warnings
#   critical_nodes: []              # Short names of critical nodes (e.g., ["MHR", "HPR"])
#   alert_channel: -1               # Channel to broadcast alerts on. -1 = disabled, 0+ = channel index
#   alert_rules: {}                 # Per-condition alert toggles/thresholds (see AlertRulesConfig)
mesh_intelligence:
  enabled: false
  regions: []
  locality_radius_miles: 8.0
  offline_threshold_hours: 2
  packet_threshold: 500
  battery_warning_percent: 30
  critical_nodes: []
  alert_channel: -1
  alert_rules: {}

# === ENVIRONMENTAL FEEDS ===
# Live situational awareness from NWS, NOAA Space Weather, and Open-Meteo.
# Provides weather alerts, HF propagation assessment, and tropospheric ducting.
#
environmental:
  enabled: false
  nws_zones:
    - "IDZ016"    # Western Magic Valley
    - "IDZ030"    # Southern Twin Falls County

  # NWS Weather Alerts (api.weather.gov)
  nws:
    enabled: true
    tick_seconds: 60
    areas: ["ID"]
    severity_min: "moderate"
    user_agent: "(meshai.example.com, ops@example.com)"  # REQUIRED by NWS

  # NOAA Space Weather (services.swpc.noaa.gov)
  swpc:
    enabled: true

  # Tropospheric ducting assessment (Open-Meteo GFS, no auth)
  ducting:
    enabled: true
    tick_seconds: 10800    # 3 hours
    latitude: 42.56        # center of mesh coverage area
    longitude: -114.47

  # NIFC Fire Perimeters (Phase 2)
  fires:
    enabled: false
    tick_seconds: 600
    state: "US-ID"

  # Avalanche Advisories (Phase 2)
  avalanche:
    enabled: false
    tick_seconds: 1800
    center_ids: ["SNFAC"]
    season_months: [12, 1, 2, 3, 4]

  # USGS Stream Gauges (waterservices.usgs.gov)
  # Find site IDs at https://waterdata.usgs.gov/nwis
  usgs:
    enabled: false
    tick_seconds: 900   # Min 15 min per USGS guidelines
    sites: []           # e.g. ["13090500", "13088000"]

  # TomTom Traffic Flow (api.tomtom.com, requires API key)
  traffic:
    enabled: false
    tick_seconds: 300
    api_key: ${TOMTOM_API_KEY}   # Secret: set via dashboard or /data/secrets/.env (get key at developer.tomtom.com)
    corridors: []
    # Example corridors:
    # - name: "I-84 Twin Falls"
    #   lat: 42.56
    #   lon: -114.47

  # 511 Road Conditions (state-specific, configurable base URL)
  roads511:
    enabled: false
    tick_seconds: 300
    api_key: ${ROADS511_API_KEY}   # Secret: set via dashboard or /data/secrets/.env (leave var empty if 511 needs no key)
    base_url: ""        # e.g. "https://511.idaho.gov/api/v2"
    endpoints: ["/get/event"]
    bbox: []            # [west, south, east, north]

  # NASA FIRMS Satellite Fire Detection
  # Early warning via satellite hotspots, hours before official perimeters
  # Get MAP_KEY at: https://firms.modaps.eosdis.nasa.gov/api/area/
  firms:
    enabled: false
    tick_seconds: 1800  # 30 min default
    map_key: ${FIRMS_MAP_KEY}    # Secret: set via dashboard or /data/secrets/.env (NASA FIRMS MAP_KEY)
    source: "VIIRS_SNPP_NRT"  # VIIRS_SNPP_NRT, VIIRS_NOAA20_NRT, MODIS_NRT
    bbox: []            # [west, south, east, north] - Required
    day_range: 1        # 1-10 days of data
    confidence_min: "nominal"  # low, nominal, high
    proximity_km: 10.0  # km to match known fire perimeters


# === NOTIFICATION DELIVERY (TRANSITIONAL) ===
# NOTE: This notifications schema will be replaced in v0.3 by the 8-toggle model.
# These rule examples are transitional until Phase 1.2 lands. Do not extend.
# Severity levels: routine (informational), priority (needs attention), immediate (act now)
#
# Route alerts to channels (mesh, email, webhook) based on rules.
# Categories match alert types from alert_engine.py.
notifications:
  enabled: false

  # Digest scheduler settings
  # The digest collects priority/routine events and delivers a summary
  # at the configured time to rules with trigger_type='schedule' and
  # schedule_match='digest'.
  digest:
    schedule: "07:00"          # HH:MM local time to fire digest
    include: []                # Toggle names to include (empty = default set)
    # Default set: weather, fire, seismic, avalanche, roads, mesh_health, tracking, other
    # Excludes rf_propagation by default
    # Example: include: ["weather", "fire", "mesh_health"]

  # Notification rules - each rule is self-contained with its own delivery config
  # Default baseline rules are created on fresh install
  rules:
    # Emergency Broadcast - all emergencies go out immediately
    - name: "Emergency Broadcast"
      enabled: true
      trigger_type: condition
      categories: []           # Empty = all categories
      min_severity: "immediate"
      delivery_type: mesh_broadcast
      broadcast_channel: 0
      cooldown_minutes: 5

    # Infrastructure Down - critical node and infrastructure offline alerts
    - name: "Infrastructure Down"
      enabled: true
      trigger_type: condition
      categories: ["infra_offline", "critical_node_down"]
      min_severity: "priority"
      delivery_type: mesh_broadcast
      broadcast_channel: 0
      cooldown_minutes: 30

    # Fire Alert - wildfire proximity and new ignition
    - name: "Fire Alert"
      enabled: true
      trigger_type: condition
      categories: ["wildfire_proximity", "new_ignition"]
      min_severity: "routine"
      delivery_type: mesh_broadcast
      broadcast_channel: 0
      cooldown_minutes: 60

    # Severe Weather - weather warnings
    - name: "Severe Weather"
      enabled: true
      trigger_type: condition
      categories: ["weather_warning"]
      min_severity: "priority"
      delivery_type: mesh_broadcast
      broadcast_channel: 0
      cooldown_minutes: 30

    # Example: Morning Digest -> mesh broadcast
    # Delivers the accumulated digest at the configured schedule time
    # - name: "Morning Digest Mesh"
    #   enabled: false
    #   trigger_type: schedule
    #   schedule_match: "digest"   # Required for digest delivery
    #   delivery_type: mesh_broadcast
    #   broadcast_channel: 0

    # Example: Morning Digest -> email
    # - name: "Morning Digest Email"
    #   enabled: false
    #   trigger_type: schedule
    #   schedule_match: "digest"
    #   delivery_type: email
    #   smtp_host: "smtp.gmail.com"
    #   smtp_port: 587
    #   smtp_user: "you@gmail.com"
    #   smtp_password: "${SMTP_PASSWORD}"
    #   smtp_tls: true
    #   from_address: "meshai@yourdomain.com"
    #   recipients: ["admin@yourdomain.com"]

    # Example: Fire alerts -> email
    # - name: "Fire Alerts Email"
    #   enabled: true
    #   trigger_type: condition
    #   categories: ["wildfire_proximity", "new_ignition"]
    #   min_severity: "routine"
    #   delivery_type: email
    #   smtp_host: "smtp.gmail.com"
    #   smtp_port: 587
    #   smtp_user: "you@gmail.com"
    #   smtp_password: "${SMTP_PASSWORD}"
    #   smtp_tls: true
    #   from_address: "meshai@yourdomain.com"
    #   recipients: ["admin@yourdomain.com"]
    #   cooldown_minutes: 30

    # Example: All warnings -> Discord webhook
    # - name: "Discord Alerts"
    #   enabled: true
    #   trigger_type: condition
    #   categories: []
    #   min_severity: "priority"
    #   delivery_type: webhook
    #   webhook_url: "https://discord.com/api/webhooks/..."
    #   cooldown_minutes: 10

    # Example: Rule with no delivery (matches and logs, but doesn't send)
    # - name: "Monitor Only"
    #   enabled: true
    #   trigger_type: condition
    #   categories: ["battery_warning"]
    #   min_severity: "priority"
    #   delivery_type: ""        # Empty = no delivery, just tracks matches

# === WEB DASHBOARD ===
dashboard:
  enabled: true
  port: 8080
  host: "0.0.0.0"
