2025-01-29 16:23:30 +03:00
|
|
|
from typing import Optional, Tuple
|
2025-01-20 14:38:41 +03:00
|
|
|
|
2024-12-02 18:41:02 +03:00
|
|
|
import numpy as np
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
|
|
|
|
|
#TODO: Реализовать поиск времени простоя
|
|
|
|
|
class DowntimeAnalyzer:
|
|
|
|
|
def __init__(self) -> None:
|
|
|
|
|
...
|
2024-12-02 18:41:02 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
def generate_downtime_report(self) -> list:
|
|
|
|
|
...
|
2024-12-02 18:41:02 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
def _separate_conditions(self, TWC_raw:pd.DataFrame, robot_raw:pd.DataFrame) -> Tuple[dict, dict]:
|
|
|
|
|
robot_splitter = RobotConditionSplitter()
|
|
|
|
|
TWC_splitter = TWC_ConditionSplitter()
|
|
|
|
|
#comm_splitter = CommConditionSplitter()
|
|
|
|
|
rob_conditions = robot_splitter.split(robot_raw)
|
|
|
|
|
TWC_conditions = TWC_splitter.split(TWC_raw)
|
|
|
|
|
#comm_df = comm_splitter.split(rob_conditions["communication"], TWC_conditions["communication"])
|
|
|
|
|
return (rob_conditions, TWC_conditions)
|
2024-12-03 12:03:52 +03:00
|
|
|
|
|
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
class ConditionSplitter:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._signals = []
|
2024-12-03 12:03:52 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
def _find_indexes(self,
|
|
|
|
|
signal: str,
|
|
|
|
|
dataframe: pd.DataFrame) -> list[list[float], list[float]]:
|
|
|
|
|
stage_diff = np.diff(dataframe[signal])
|
|
|
|
|
start_idx = np.where(stage_diff == 1)
|
|
|
|
|
finish_idx = np.where(stage_diff == -1)
|
|
|
|
|
return start_idx[0], finish_idx[0]
|
|
|
|
|
|
|
|
|
|
def _find_events(self,
|
|
|
|
|
dataframe: pd.DataFrame,
|
|
|
|
|
signals: list[str]) -> Optional[dict[dict[pd.Series]]]:
|
|
|
|
|
intervals = {}
|
|
|
|
|
end_time = 0
|
|
|
|
|
for signal in signals:
|
|
|
|
|
start_idx, finish_idx = np.array(self._find_indexes(signal, dataframe))
|
|
|
|
|
start_series = dataframe.loc[start_idx, "time"].reset_index(drop=True)
|
|
|
|
|
end_series = dataframe.loc[finish_idx, "time"].reset_index(drop=True)
|
|
|
|
|
end_series.fillna(end_time)
|
|
|
|
|
intervals[signal] = {"rise": start_series,
|
|
|
|
|
"fall": end_series}
|
|
|
|
|
return intervals
|
|
|
|
|
|
|
|
|
|
def _form_intervals(self,
|
|
|
|
|
start: pd.Series,
|
|
|
|
|
end: pd.Series) -> dict:
|
|
|
|
|
if len(start) != len(end):
|
|
|
|
|
for i in range(1, len(end)):
|
|
|
|
|
if end[i-1] > start[i]:
|
|
|
|
|
start = start.drop(i).reset_index(drop=True)
|
|
|
|
|
intervals = {'start':start.tolist, 'end':end.tolist}
|
|
|
|
|
return intervals
|
|
|
|
|
|
2024-12-03 12:03:52 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
class RobotConditionSplitter(ConditionSplitter):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._signals = [
|
|
|
|
|
"$OUT3012",
|
|
|
|
|
"$IN3003",
|
|
|
|
|
"$OUT3003",
|
|
|
|
|
"$OUT3244"
|
|
|
|
|
]
|
2024-12-03 12:03:52 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
def split(self, dataframe: pd.DataFrame) -> dict:
|
|
|
|
|
events = self._find_events(dataframe, self._signals)
|
|
|
|
|
communication_sig = {'sent':events["$OUT3244"]["fall"], 'received':events[""][""]}
|
|
|
|
|
point_interval = self._form_intervals(start=events["$OUT3012"]["rise"], end=events["$OUT3012"]["fall"])
|
|
|
|
|
movement_interval = self._form_intervals(start=events["$OUT3244"]["rise"], end=events["$OUT3244"]["fall"])
|
|
|
|
|
conditions = {"communication":communication_sig, "waiting": point_interval, "moving": movement_interval}
|
|
|
|
|
return conditions
|
2024-12-03 12:03:52 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
|
|
|
|
|
class TWC_ConditionSplitter(ConditionSplitter):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._signals = [
|
|
|
|
|
"Closing",
|
|
|
|
|
"Squeeze",
|
|
|
|
|
"Welding",
|
|
|
|
|
"Relief",
|
|
|
|
|
"Oncoming"
|
|
|
|
|
]
|
2024-12-02 18:41:02 +03:00
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
def split(self, dataframe: pd.DataFrame) -> dict:
|
|
|
|
|
events = self._find_events(dataframe, self._signals)
|
|
|
|
|
communication_sig = {'sent':events[""][""], 'received':events[""][""]} #ситара что-то делает -конец сигнала
|
|
|
|
|
closing_interval = self._form_intervals(start=events["Closing"]["rise"], end=events["Closing"]["fall"])
|
|
|
|
|
squeeze_interval = self._form_intervals(start=events["Squeeze"]["rise"], end=events["Squeeze"]["fall"])
|
|
|
|
|
relief_interval = self._form_intervals(start=events["Relief"]["rise"], end=events["Relief"]["fall"])
|
|
|
|
|
oncoming_interval = self._form_intervals(start=events["Oncoming"]["rise"], end=events["Oncoming"]["fall"])
|
|
|
|
|
conditions = {
|
|
|
|
|
"communication":communication_sig,
|
|
|
|
|
'closing':closing_interval,
|
|
|
|
|
'squeeze':squeeze_interval,
|
|
|
|
|
'relief':relief_interval,
|
|
|
|
|
'oncoming':oncoming_interval
|
|
|
|
|
}
|
|
|
|
|
return conditions
|
2024-12-02 18:41:02 +03:00
|
|
|
|
|
|
|
|
|
2025-01-29 16:23:30 +03:00
|
|
|
class CommConditionSplitter(ConditionSplitter):
|
|
|
|
|
"""
|
|
|
|
|
Определяет промежуток, в который происходит взаимодействие между нодами.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def split(self, node1: dict, node2: dict) -> pd.DataFrame:
|
|
|
|
|
n1_to_n2 = self._form_intervals(start=node1['sent'], end=node2['received'])
|
|
|
|
|
n2_to_n1 = self._form_intervals(start=node2['sent'], end=node1['received'])
|
|
|
|
|
return pd.concat([pd.DataFrame(n1_to_n2), pd.DataFrame(n2_to_n1)])
|
|
|
|
|
|
|
|
|
|
|
2024-12-02 18:41:02 +03:00
|
|
|
if __name__ == "__main__":
|
|
|
|
|
path = "D:\downloads\Test2\TeslaTIME29_71_KRCIO.dat"
|