mrDarker
9 天以前 829fe6c6bc33d53fda9c31fd45a37e1df87befff
SourceCode/Bond/Servo/ProductionStats.h
对比新文件
@@ -0,0 +1,66 @@
#pragma once
#include <chrono>
#include <map>
#include <string>
class CConfiguration;
enum class ProductionShiftType : int {
   Day = 1,
   Night = 2
};
struct ProductionShiftWindow {
   ProductionShiftType type{ ProductionShiftType::Day };
   std::chrono::system_clock::time_point start{};
   std::chrono::system_clock::time_point end{};
   std::string startLocal;   // "YYYY-MM-DD HH:MM:SS"
   std::string endLocal;     // "YYYY-MM-DD HH:MM:SS"
   std::string startUtcIso;  // "YYYY-MM-DDTHH:MM:SSZ"
   std::string endUtcIso;    // "YYYY-MM-DDTHH:MM:SSZ"
};
struct ProductionOutputSummary {
   long long pairsTotal = 0;        // "瀵规暟"
   long long pairsPass = 0;
   long long pairsFail = 0;
   long long pairsNoResult = 0;
   double yield = 0.0;              // pairsPass / (pairsPass + pairsFail), 0 if denom==0
   // Average takt time derived from glass_log.t_start/t_end (per pair, seconds)
   double avgTaktSeconds = 0.0;
   long long taktSamplePairs = 0;
};
struct ProductionAlarmSummary {
   int alarmsTriggered = 0;         // start_time within shift window
   int alarmsOverlapping = 0;       // overlaps shift window (including active)
   double downtimeMinutes = 0.0;    // overlap minutes (best-effort)
   std::map<int, int> bySeverity;   // severity_level -> count (overlapping)
};
struct ProductionTransferSummary {
   int transfersFinished = 0;        // end_time within shift window
   std::map<std::string, int> byStatus;
   double avgCreateToEndSeconds = 0.0;
};
struct ProductionShiftSummary {
   ProductionShiftWindow window;
   ProductionOutputSummary output;
   ProductionAlarmSummary alarms;
   ProductionTransferSummary transfers;
};
class ProductionStats {
public:
   static bool GetCurrentShiftWindow(CConfiguration& config, ProductionShiftWindow& outWindow);
   static bool ComputeCurrentShiftSummary(CConfiguration& config, ProductionShiftSummary& outSummary);
   static void LogCurrentShiftSummary(CConfiguration& config);
   // Computes "current shift" and its adjacent other shift, so UI can always show Day+Night numbers.
   // - If current is Day: day=current day shift, night=previous night shift.
   // - If current is Night: night=current night shift, day=previous day shift.
   static bool ComputeDayNightSummaries(CConfiguration& config, ProductionShiftSummary& outDay, ProductionShiftSummary& outNight);
};