Refactor CANveyor dashboard architecture

- Replace `stats.utils.extractor` with dedicated `loader` and
  `converter`
  modules to improve code organization.
- Implement explicit pipeline stages for ingestion, decoding, and
  precomputation with caching.
- Standardize data loading and J1939 parsing logic across sub-modules.
- Enhance dashboard responsiveness by pre-calculating figures and
  downsampling ID-grouped data.
- Enforce strict typing and add docstrings to public components.
This commit is contained in:
2026-07-23 16:01:34 +02:00
parent 89a9124a83
commit 4f280da033
8 changed files with 575 additions and 440 deletions
+8 -9
View File
@@ -1,23 +1,21 @@
# File: entropy.py
# File: stats/entropy.py
# Copyright (C) 2026 Erick Ahmed
# SPDX-License-Identifier: AGPL-3.0-or-later
"""CAN bus byte-level entropy analyzer and plotter."""
import argparse
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
from typing import List
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from stats.utils.extractor import load_data
from stats.utils.extractor import to_int
from stats.utils.converter import format_can_id_vec as _format_can_id_vec, to_int
from stats.utils.loader import load_data
def _format_can_id_vec(s: pd.Series) -> pd.Series:
s = s.astype('string').str.strip()
s = s.str.replace(r'^0x', '', case=False, regex=True)
s = s.str.upper()
return s.fillna('UNKNOWN').replace('', 'UNKNOWN')
def _entropy_col(a: np.ndarray) -> float:
a = a[~np.isnan(a)]
@@ -36,6 +34,7 @@ def _entropy_col(a: np.ndarray) -> float:
p = counts / counts.sum()
return float(-np.sum(p * np.log2(p)))
def calculate_byte_entropy(df: pd.DataFrame) -> pd.DataFrame:
available_cols = [f"b{i}" for i in range(8) if f"b{i}" in df.columns]
if not available_cols:
@@ -64,7 +63,7 @@ def calculate_byte_entropy(df: pd.DataFrame) -> pd.DataFrame:
else:
groups = []
def _process_group(sub):
def _process_group(sub: np.ndarray) -> np.ndarray:
res = np.zeros(n_cols, dtype=np.float64)
for ci in range(n_cols):
res[ci] = _entropy_col(sub[:, ci])