using EasyPipes; using SoraV2Tools; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SoraV2Utils_Service { public class DeviceTracker { public static DeviceTracker Instance; private bool BatteryWarningSent = false; private bool BatteryCriticalSent = false; private bool RechargeCompletedSent = false; private Dictionary BatteryStats = new Dictionary(); public DeviceStatus _DeviceStatus; public DeviceTracker() { Instance = this; } public void processMouseData(DeviceStatus deviceStatus) { _DeviceStatus = deviceStatus; if (deviceStatus.Charging == 0) { BatteryStats.Add(DateTime.Now, deviceStatus.Battery); RechargeCompletedSent = false; if (deviceStatus.Battery <= ServiceSettings.Instance.criticalThreshold && !BatteryCriticalSent && deviceStatus.Charging != 1) { Notification.TwoLine(String.Format("SoraV2 battery is at {0}%",deviceStatus.Battery), "Please recharge now!"); BatteryCriticalSent = true; } else if (deviceStatus.Battery <= ServiceSettings.Instance.warningThreshold && !BatteryCriticalSent && !BatteryWarningSent && deviceStatus.Charging != 1) { Notification.TwoLine(String.Format("SoraV2 battery is at {0}%", deviceStatus.Battery), "Please consider recharching."); BatteryWarningSent = true; } } else if (deviceStatus.Charging == 1 && !RechargeCompletedSent) { BatteryStats.Clear(); BatteryWarningSent = false; BatteryCriticalSent = false; RechargeCompletedSent = true; if (deviceStatus.Battery == 100) { Notification.SingleLine(String.Format("SoraV2 battery fully recharged!")); } } } public double CalculateConsumptionRate() { // Ensure there's enough data to calculate a rate (at least two points) if (this.BatteryStats.Count > 2) { // Get the last two entries in the dictionary var latestEntry = this.BatteryStats.Last(); var previousEntry = this.BatteryStats.ElementAt(this.BatteryStats.Count - 2); // Calculate the difference in battery level and time double batteryLevelDifference = previousEntry.Value - latestEntry.Value; double timeDifferenceMinutes = (latestEntry.Key - previousEntry.Key).TotalMinutes; // Calculate consumption rate (percentage per minute) return batteryLevelDifference / timeDifferenceMinutes; } return 0; } public double EstimateRemainingRuntime() { if (this.BatteryStats == null || this.BatteryStats.Count < 2) { return -1; } var sortedStats = new SortedDictionary(this.BatteryStats); double totalConsumptionRate = 0; int numberOfIntervals = 0; DateTime previousTime = DateTime.MinValue; byte previousBatteryLevel = 0; // Calculate the average consumption rate per second foreach (var entry in sortedStats) { if (previousTime != DateTime.MinValue) { // Calculate the time difference (in seconds) double timeDifferenceInSeconds = (entry.Key - previousTime).TotalSeconds; // Calculate the battery consumption for this interval int batteryDifference = previousBatteryLevel - entry.Value; // Ensure the consumption is positive (in case of rounding errors) if (batteryDifference > 0) { // Calculate consumption rate per second double consumptionRate = batteryDifference / timeDifferenceInSeconds; totalConsumptionRate += consumptionRate; numberOfIntervals++; } } previousTime = entry.Key; previousBatteryLevel = entry.Value; } // Calculate the average consumption rate double averageConsumptionRate = totalConsumptionRate / numberOfIntervals; // Get the current battery level (from the last entry in the sorted dictionary) byte currentBatteryLevel = sortedStats.Values.Last(); // Calculate the remaining runtime (in seconds) double remainingRuntimeInSeconds = currentBatteryLevel / averageConsumptionRate; // Convert seconds to a more human-readable format (hours, minutes, seconds) TimeSpan remainingTime = TimeSpan.FromSeconds(remainingRuntimeInSeconds); Console.WriteLine($"Estimated remaining battery runtime: {remainingTime.Hours} hours, {remainingTime.Minutes} minutes, {remainingTime.Seconds} seconds."); return remainingRuntimeInSeconds; } } }