Skip to content
Svyatoslav Rogozin edited this page Dec 11, 2024 · 2 revisions

Application Workflow

This wiki outlines the backend and frontend workflows for the application, providing an overview of key components, their interconnections, and operational guidelines.


Backend Workflow

The backend is built using a Python Flask application. It handles API requests, processes data, and manages the database.

1. Application Setup

  • Framework: Flask serves as the web framework.
  • CORS: Enabled using flask_cors to allow API requests from specific origins.
  • File Structure:
    • station_status_app.py: Main application logic.
    • config.yaml: Database and table configuration.
    • templates/index.html: Placeholder for the homepage.

2. Configuration Loading

  • The load_config function reads config.yaml for settings such as:
    • Database connection details.
    • Table mappings and respective columns.
  • Missing configuration files log an error and terminate the application.

3. Logging

  • Logs are written to app.log with:
    • Log Level: INFO
    • Format: timestamp - loglevel - message
    • Encoding: UTF-8

4. Database Connection

  • The get_connection function uses ODBC Driver 18 for SQL Server to connect to the database, with credentials from config.yaml.
  • Errors are logged for troubleshooting.

5. Data Fetching

  • The fetch_data function retrieves table data by:
    • Querying the latest timestamp (TmStamp).
    • Filtering data within a calculated time range.
    • Returning results as a list of dictionaries.

6. Data Status Calculation

High-Frequency (HF) Data
  • Function: calculate_hf_status
  • Purpose: Evaluates HF data by:
    • Checking total rows.
    • Identifying missing columns and values.
    • Detecting issues like excessive NA values or identical consecutive readings.
  • Outcome: Status ("Online" or "Offline") and a list of violations.
Low-Frequency (LF) Data
  • Function: calculate_lf_status
  • Purpose: Assesses LF data for:
    • Sufficient observations.
    • Consecutive invalid values (e.g., NA).
  • Outcome: Similar to HF data.

7. Quality Metrics

  • The calculate_quality_data function generates statistics for specified columns:
    • Total non-NA values.
    • Mean values (if applicable).

8. API Endpoint

  • Endpoint: /api/station_combined_status/<station_name>
  • Workflow:
    1. Validates the station name.
    2. Retrieves HF and LF table configurations.
    3. Fetches HF and LF data.
    4. Calculates quality metrics and status.
    5. Combines metrics, statuses, and violations into a JSON response.
    6. Returns the response with timestamps and an overall status.

9. Time Management

  • Timestamps are in UTC and converted if needed using datetime and pytz.

10. Application Execution

  • Flask app runs with:
    • Debug Mode: Enabled (for development).
    • Host: 0.0.0.0 (binds to all interfaces).
    • Port: 5000.

Backend Workflow Summary

  1. User requests station status via API.
  2. Backend validates and fetches data.
  3. Quality metrics and statuses are calculated.
  4. JSON response is prepared and sent to the frontend.

Frontend Workflow

The frontend is built to provide an interactive map interface for displaying EC station statuses.

1. Application Setup

  • Framework: React serves as the frontend framework.
  • Map Integration: Leaflet.js is used for rendering the map and handling geospatial data.

2. Station Management

  • Station Configuration:
    • Example:
      const stations = [
          {
              name: "StationA",
              fullName: "Station A Full Name",
              coords: [58.123, 26.789],
              apiUrl: "https://example.com/api/status/StationA"
          }
      ];
      export default stations;

3. Map Rendering

  • The Map.js component:
    • Initializes the map with predefined bounds and zoom levels.
    • Loads station markers dynamically by fetching status data from the backend API.
    • Example:
      const map = L.map('map', {
          minZoom: 7,
          maxZoom: 12,
          maxBounds: [[57.9, 25.5], [58.9, 27.5]]
      }).setView([58.3, 26.5], 8);

4. Data Integration

  • Fetch station data using the fetchStationData utility function.
  • Add markers for each station:
    stations.forEach(async (station) => {
        const data = await fetchStationData(station.apiUrl);
        const marker = L.marker(station.coords).bindPopup(`${station.fullName}: ${data.status}`);
        marker.addTo(map);
    });

5. Styling

  • CSS for styling map markers is managed in src/styles/map.css.
  • Example:
    .station-marker {
        background-color: white;
        border: 2px solid black;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
    }

Frontend Workflow Summary

  1. Map is initialized and rendered with Leaflet.
  2. Station data is fetched from the backend API.
  3. Markers are dynamically added to the map.
  4. Users interact with the map to view station statuses.