From 829fe6c6bc33d53fda9c31fd45a37e1df87befff Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期五, 30 一月 2026 11:16:24 +0800
Subject: [PATCH] Merge branch 'clh' into liuyang

---
 SourceCode/Bond/Servo/ProductionStats.h |   66 +++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/SourceCode/Bond/Servo/ProductionStats.h b/SourceCode/Bond/Servo/ProductionStats.h
new file mode 100644
index 0000000..c884228
--- /dev/null
+++ b/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);
+};

--
Gitblit v1.9.3