void UpdateGroupedDevices() { foreach (DestinationOSDeviceInfo driver in allDrivers.DownloadedDestinationOSDrivers) { DestinationOSDevicesGroup destinationOSDevicesGroup = GroupedDevices.Where(g => g.DeviceClass == driver.DeviceClass).FirstOrDefault(); if (destinationOSDevicesGroup == null) { GroupedDevices.Add(new DestinationOSDevicesGroup(driver.DeviceClass, driver.DeviceClassName, driver.DeviceClassImageSmall, new List <DestinationOSDeviceInfo> { driver })); } else { destinationOSDevicesGroup.Drivers.Add(driver); } } OrderedDeviceGroups = CollectionViewSource.GetDefaultView(GroupedDevices); OrderedDeviceGroups.SortDescriptions.Clear(); OrderedDeviceGroups.SortDescriptions.Add(new SortDescription("Order", ListSortDirection.Ascending)); OrderedDeviceGroups.Refresh(); }
public async Task SwichMostProfitableGroupUpMethod(Dictionary <AlgorithmType, NiceHashSMA> NiceHashData, bool log = true) { #if (SWITCH_TESTING) MiningDevice.SetNextTest(); #endif List <MiningPair> profitableDevices = new List <MiningPair>(); double CurrentProfit = 0.0d; double PrevStateProfit = 0.0d; foreach (var device in _miningDevices) { // calculate profits device.CalculateProfits(NiceHashData); // check if device has profitable algo if (device.HasProfitableAlgo()) { profitableDevices.Add(device.GetMostProfitablePair()); CurrentProfit += device.GetCurrentMostProfitValue; PrevStateProfit += device.GetPrevMostProfitValue; } } // print profit statuses if (log) { StringBuilder stringBuilderFull = new StringBuilder(); stringBuilderFull.AppendLine("Current device profits:"); foreach (var device in _miningDevices) { StringBuilder stringBuilderDevice = new StringBuilder(); stringBuilderDevice.AppendLine(String.Format("\tProfits for {0} ({1}):", device.Device.UUID, device.Device.GetFullName())); foreach (var algo in device.Algorithms) { stringBuilderDevice.AppendLine(String.Format("\t\tPROFIT = {0}\t(SPEED = {1}\t\t| NHSMA = {2})\t[{3}]", algo.CurrentProfit.ToString(DOUBLE_FORMAT), // Profit algo.AvaragedSpeed + (algo.IsDual() ? "/" + algo.SecondaryAveragedSpeed : ""), // Speed algo.CurNhmSMADataVal + (algo.IsDual() ? "/" + algo.SecondaryCurNhmSMADataVal : ""), // NiceHashData algo.AlgorithmStringID // Name )); } // most profitable stringBuilderDevice.AppendLine(String.Format("\t\tMOST PROFITABLE ALGO: {0}, PROFIT: {1}", device.GetMostProfitableString(), device.GetCurrentMostProfitValue.ToString(DOUBLE_FORMAT))); stringBuilderFull.AppendLine(stringBuilderDevice.ToString()); } Helpers.ConsolePrint(TAG, stringBuilderFull.ToString()); } // check if should mine // Only check if profitable inside this method when getting SMA data, cheching during mining is not reliable if (CheckIfShouldMine(CurrentProfit, log) == false) { foreach (var device in _miningDevices) { device.SetNotMining(); } return; } // check profit threshold Helpers.ConsolePrint(TAG, String.Format("PrevStateProfit {0}, CurrentProfit {1}", PrevStateProfit, CurrentProfit)); if (PrevStateProfit > 0 && CurrentProfit > 0) { double a = Math.Max(PrevStateProfit, CurrentProfit); double b = Math.Min(PrevStateProfit, CurrentProfit); //double percDiff = Math.Abs((PrevStateProfit / CurrentProfit) - 1); double percDiff = ((a - b)) / b; if (percDiff < ConfigManager.GeneralConfig.SwitchProfitabilityThreshold) { // don't switch Helpers.ConsolePrint(TAG, String.Format("Will NOT switch profit diff is {0}, current threshold {1}", percDiff, ConfigManager.GeneralConfig.SwitchProfitabilityThreshold)); // RESTORE OLD PROFITS STATE foreach (var device in _miningDevices) { device.RestoreOldProfitsState(); } if (!Miner.SHOULD_START_DONATING) { return; } } else { Helpers.ConsolePrint(TAG, String.Format("Will SWITCH profit diff is {0}, current threshold {1}", percDiff, ConfigManager.GeneralConfig.SwitchProfitabilityThreshold)); } } // group new miners Dictionary <string, List <MiningPair> > newGroupedMiningPairs = new Dictionary <string, List <MiningPair> >(); // group devices with same supported algorithms { var currentGroupedDevices = new List <GroupedDevices>(); for (int first = 0; first < profitableDevices.Count; ++first) { var firstDev = profitableDevices[first].Device; // check if is in group bool isInGroup = false; foreach (var groupedDevices in currentGroupedDevices) { if (groupedDevices.Contains(firstDev.UUID)) { isInGroup = true; break; } } // if device is not in any group create new group and check if other device should group if (isInGroup == false) { var newGroup = new GroupedDevices(); var miningPairs = new List <MiningPair>() { profitableDevices[first] }; newGroup.Add(firstDev.UUID); for (int second = first + 1; second < profitableDevices.Count; ++second) { // check if we should group var firstPair = profitableDevices[first]; var secondPair = profitableDevices[second]; if (GroupingLogic.ShouldGroup(firstPair, secondPair)) { var secondDev = profitableDevices[second].Device; newGroup.Add(secondDev.UUID); miningPairs.Add(profitableDevices[second]); } } currentGroupedDevices.Add(newGroup); newGroupedMiningPairs[CalcGroupedDevicesKey(newGroup)] = miningPairs; } } } //bool IsMinerStatsCheckUpdate = false; { // check which groupMiners should be stopped and which ones should be started and which to keep running Dictionary <string, GroupMiner> toStopGroupMiners = new Dictionary <string, GroupMiner>(); Dictionary <string, GroupMiner> toRunNewGroupMiners = new Dictionary <string, GroupMiner>(); Dictionary <string, GroupMiner> noChangeGroupMiners = new Dictionary <string, GroupMiner>(); // check what to stop/update foreach (string runningGroupKey in _runningGroupMiners.Keys) { if (newGroupedMiningPairs.ContainsKey(runningGroupKey) == false) { // runningGroupKey not in new group definately needs to be stopped and removed from curently running toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } // If we need to start donating, stop everything else if (!Miner.IS_DONATING && Miner.SHOULD_START_DONATING) { toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; Miner.IS_DONATING = true; } else if (Miner.IS_DONATING && Miner.SHOULD_STOP_DONATING) { toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; Miner.DonationStart = Miner.DonationStart.Add(Miner.DonateEvery); Miner.IS_DONATING = false; } else { // runningGroupKey is contained but needs to check if mining algorithm is changed var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); if (newAlgoType != AlgorithmType.NONE && newAlgoType != AlgorithmType.INVALID) { // if algoType valid and different from currently running update if (newAlgoType != _runningGroupMiners[runningGroupKey].DualAlgorithmType) { // remove current one and schedule to stop mining toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; // create new one TODO check if DaggerHashimoto GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } else { noChangeGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } } } } // check brand new foreach (var kvp in newGroupedMiningPairs) { var key = kvp.Key; var miningPairs = kvp.Value; if (_runningGroupMiners.ContainsKey(key) == false) { GroupMiner newGroupMiner = new GroupMiner(miningPairs, key); toRunNewGroupMiners[key] = newGroupMiner; } } if ((toStopGroupMiners.Values.Count > 0) || (toRunNewGroupMiners.Values.Count > 0)) { StringBuilder stringBuilderPreviousAlgo = new StringBuilder(); StringBuilder stringBuilderCurrentAlgo = new StringBuilder(); StringBuilder stringBuilderNoChangeAlgo = new StringBuilder(); // stop old miners foreach (var toStop in toStopGroupMiners.Values) { stringBuilderPreviousAlgo.Append(String.Format("{0}: {1}, ", toStop.DevicesInfoString, toStop.AlgorithmType)); toStop.Stop(); _runningGroupMiners.Remove(toStop.Key); // TODO check if daggerHashimoto and save if (toStop.AlgorithmType == AlgorithmType.DaggerHashimoto) { if (toStop.DeviceType == DeviceType.NVIDIA) { _ethminerNVIDIAPaused = toStop; } else if (toStop.DeviceType == DeviceType.AMD) { _ethminerAMDPaused = toStop; } } } // start new miners foreach (var toStart in toRunNewGroupMiners.Values) { stringBuilderCurrentAlgo.Append(String.Format("{0}: {1}, ", toStart.DevicesInfoString, toStart.AlgorithmType)); toStart.Start(_miningLocation, _btcAdress, _worker); _runningGroupMiners[toStart.Key] = toStart; } // which miners dosen't change foreach (var noChange in noChangeGroupMiners.Values) { stringBuilderNoChangeAlgo.Append(String.Format("{0}: {1}, ", noChange.DevicesInfoString, noChange.AlgorithmType)); } if (stringBuilderPreviousAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("Stop Mining: {0}", stringBuilderPreviousAlgo.ToString())); } if (stringBuilderCurrentAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("Now Mining : {0}", stringBuilderCurrentAlgo.ToString())); } if (stringBuilderNoChangeAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("No change : {0}", stringBuilderNoChangeAlgo.ToString())); } } } // stats quick fix code //if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { await MinerStatsCheck(NiceHashData); //} }
public void SwichMostProfitableGroupUpMethod(Dictionary <AlgorithmType, NiceHashSMA> NiceHashData, bool log = true) { List <MiningDevice> profitableDevices = new List <MiningDevice>(); double CurrentProfit = 0.0d; foreach (var device in _miningDevices) { // calculate profits device.CalculateProfits(NiceHashData); // check if device has profitable algo if (device.MostProfitableKey != AlgorithmType.NONE) { profitableDevices.Add(device); CurrentProfit += device.GetCurrentMostProfitValue; device.Device.MostProfitableAlgorithm = device.Algorithms[device.MostProfitableKey].algoRef; } } // print profit statuses if (log) { StringBuilder stringBuilderFull = new StringBuilder(); stringBuilderFull.AppendLine("Current device profits:"); foreach (var device in _miningDevices) { StringBuilder stringBuilderDevice = new StringBuilder(); stringBuilderDevice.AppendLine(String.Format("\tProfits for {0} ({1}):", device.Device.UUID, device.Device.Name)); foreach (var algo in device.Algorithms) { stringBuilderDevice.AppendLine(String.Format("\t\tPROFIT = {0}\t(SPEED = {1}\t\t| NHSMA = {2})\t[{3}]", algo.Value.CurrentProfit.ToString(DOUBLE_FORMAT), // Profit algo.Value.AvaragedSpeed, // Speed algo.Value.CurNhmSMADataVal, // NiceHashData AlgorithmNiceHashNames.GetName(algo.Key) // Name )); } // most profitable stringBuilderDevice.AppendLine(String.Format("\t\tMOST PROFITABLE ALGO: {0}, PROFIT: {1}", AlgorithmNiceHashNames.GetName(device.MostProfitableKey), device.GetCurrentMostProfitValue.ToString(DOUBLE_FORMAT))); stringBuilderFull.AppendLine(stringBuilderDevice.ToString()); } Helpers.ConsolePrint(TAG, stringBuilderFull.ToString()); } // check if should mine if (CheckIfShouldMine(CurrentProfit, log) == false) { return; } // group devices with same supported algorithms _previousAllGroupedDevices = _currentAllGroupedDevices; _currentAllGroupedDevices = new List <SortedSet <string> >(); Dictionary <GroupedDevices, Algorithm> newGroupAndAlgorithm = new Dictionary <GroupedDevices, Algorithm>(); for (int first = 0; first < profitableDevices.Count; ++first) { var firstDev = profitableDevices[first].Device; // skip if no algorithm is profitable if (firstDev.MostProfitableAlgorithm == null) { if (log) { Helpers.ConsolePrint("SwichMostProfitableGroupUpMethod", String.Format("Device {0}, MostProfitableAlgorithm == null", firstDev.Name)); } continue; } // check if is in group bool isInGroup = false; foreach (var groupedDevices in _currentAllGroupedDevices) { if (groupedDevices.Contains(firstDev.UUID)) { isInGroup = true; break; } } if (isInGroup) { continue; } var newGroup = new GroupedDevices(); newGroup.Add(firstDev.UUID); for (int second = first + 1; second < profitableDevices.Count; ++second) { var secondDev = profitableDevices[second].Device; // first check if second device has profitable algorithm if (secondDev.MostProfitableAlgorithm != null) { // check if we should group if (GroupingLogic.IsEquihashGroupLogic(firstDev, secondDev) || GroupingLogic.IsDaggerAndSameComputePlatform(firstDev, secondDev) || GroupingLogic.IsGroupBinaryAndAlgorithmSame(firstDev, secondDev)) { newGroup.Add(secondDev.UUID); } } } _currentAllGroupedDevices.Add(newGroup); newGroupAndAlgorithm.Add(newGroup, firstDev.MostProfitableAlgorithm); } // stop groupes that aren't in current group devices foreach (var curPrevGroup in _previousAllGroupedDevices) { var curPrevGroupKey = CalcGroupedDevicesKey(curPrevGroup); bool contains = false; foreach (var curCheckGroup in _currentAllGroupedDevices) { var curCheckGroupKey = CalcGroupedDevicesKey(curCheckGroup); if (curPrevGroupKey == curCheckGroupKey) { contains = true; break; } } if (!contains) { _groupedDevicesMiners[curPrevGroupKey].Stop(); } } // switch to newGroupAndAlgorithm most profitable algorithm foreach (var kvpGroupAlgorithm in newGroupAndAlgorithm) { var group = kvpGroupAlgorithm.Key; var algorithm = kvpGroupAlgorithm.Value; GroupMiners currentGroupMiners; // try find if it doesn't exist create new string groupStringKey = CalcGroupedDevicesKey(group); if (!_groupedDevicesMiners.TryGetValue(groupStringKey, out currentGroupMiners)) { currentGroupMiners = new GroupMiners(group); _groupedDevicesMiners.Add(groupStringKey, currentGroupMiners); } currentGroupMiners.StartAlgorihtm(algorithm, _miningLocation, _workerBtcStringWorker); } // stats quick fix code if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { MinerStatsCheck(NiceHashData); } }
private void SwichMostProfitableGroupUpMethod(object sender, SmaUpdateEventArgs e) { #if (SWITCH_TESTING) MiningDevice.SetNextTest(); #endif var profitableDevices = new List <MiningPair>(); var currentProfit = 0.0d; var prevStateProfit = 0.0d; foreach (var device in _miningDevices) { // calculate profits device.CalculateProfits(e.NormalizedProfits); // check if device has profitable algo if (device.HasProfitableAlgo()) { profitableDevices.Add(device.GetMostProfitablePair()); currentProfit += device.GetCurrentMostProfitValue; prevStateProfit += device.GetPrevMostProfitValue; } } var stringBuilderFull = new StringBuilder(); stringBuilderFull.AppendLine("Current device profits:"); foreach (var device in _miningDevices) { var stringBuilderDevice = new StringBuilder(); stringBuilderDevice.AppendLine($"\tProfits for {device.Device.Uuid} ({device.Device.GetFullName()}):"); foreach (var algo in device.Algorithms) { stringBuilderDevice.AppendLine( $"\t\tPROFIT = {algo.CurrentProfit.ToString(DoubleFormat)}" + $"\t(SPEED = {algo.AvaragedSpeed:e5}" + $"\t\t| NHSMA = {algo.CurNhmSmaDataVal:e5})" + $"\t[{algo.AlgorithmStringID}]" ); if (algo is DualAlgorithm dualAlg) { stringBuilderDevice.AppendLine( $"\t\t\t\t\t Secondary:\t\t {dualAlg.SecondaryAveragedSpeed:e5}" + $"\t\t\t\t {dualAlg.SecondaryCurNhmSmaDataVal:e5}" ); } } // most profitable stringBuilderDevice.AppendLine( $"\t\tMOST PROFITABLE ALGO: {device.GetMostProfitableString()}, PROFIT: {device.GetCurrentMostProfitValue.ToString(DoubleFormat)}"); stringBuilderFull.AppendLine(stringBuilderDevice.ToString()); } Helpers.ConsolePrint(Tag, stringBuilderFull.ToString()); // check if should mine // Only check if profitable inside this method when getting SMA data, cheching during mining is not reliable if (CheckIfShouldMine(currentProfit) == false) { foreach (var device in _miningDevices) { device.SetNotMining(); } return; } // check profit threshold Helpers.ConsolePrint(Tag, $"PrevStateProfit {prevStateProfit}, CurrentProfit {currentProfit}"); if (prevStateProfit > 0 && currentProfit > 0) { var a = Math.Max(prevStateProfit, currentProfit); var b = Math.Min(prevStateProfit, currentProfit); //double percDiff = Math.Abs((PrevStateProfit / CurrentProfit) - 1); var percDiff = ((a - b)) / b; if (percDiff < ConfigManager.GeneralConfig.SwitchProfitabilityThreshold) { // don't switch Helpers.ConsolePrint(Tag, $"Will NOT switch profit diff is {percDiff}, current threshold {ConfigManager.GeneralConfig.SwitchProfitabilityThreshold}"); // RESTORE OLD PROFITS STATE foreach (var device in _miningDevices) { device.RestoreOldProfitsState(); } return; } Helpers.ConsolePrint(Tag, $"Will SWITCH profit diff is {percDiff}, current threshold {ConfigManager.GeneralConfig.SwitchProfitabilityThreshold}"); } // group new miners var newGroupedMiningPairs = new Dictionary <string, List <MiningPair> >(); // group devices with same supported algorithms { var currentGroupedDevices = new List <GroupedDevices>(); for (var first = 0; first < profitableDevices.Count; ++first) { var firstDev = profitableDevices[first].Device; // check if is in group var isInGroup = currentGroupedDevices.Any(groupedDevices => groupedDevices.Contains(firstDev.Uuid)); // if device is not in any group create new group and check if other device should group if (isInGroup == false) { var newGroup = new GroupedDevices(); var miningPairs = new List <MiningPair>() { profitableDevices[first] }; newGroup.Add(firstDev.Uuid); for (var second = first + 1; second < profitableDevices.Count; ++second) { // check if we should group var firstPair = profitableDevices[first]; var secondPair = profitableDevices[second]; if (GroupingLogic.ShouldGroup(firstPair, secondPair)) { var secondDev = profitableDevices[second].Device; newGroup.Add(secondDev.Uuid); miningPairs.Add(profitableDevices[second]); } } currentGroupedDevices.Add(newGroup); newGroupedMiningPairs[CalcGroupedDevicesKey(newGroup)] = miningPairs; } } } //bool IsMinerStatsCheckUpdate = false; { // check which groupMiners should be stopped and which ones should be started and which to keep running var toStopGroupMiners = new Dictionary <string, GroupMiner>(); var toRunNewGroupMiners = new Dictionary <string, GroupMiner>(); var noChangeGroupMiners = new Dictionary <string, GroupMiner>(); // check what to stop/update foreach (var runningGroupKey in _runningGroupMiners.Keys) { if (newGroupedMiningPairs.ContainsKey(runningGroupKey) == false) { // runningGroupKey not in new group definately needs to be stopped and removed from curently running toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } else { // runningGroupKey is contained but needs to check if mining algorithm is changed var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); if (newAlgoType != AlgorithmType.NONE && newAlgoType != AlgorithmType.INVALID) { // Check if dcri optimal value has changed var dcriChanged = false; foreach (var mPair in _runningGroupMiners[runningGroupKey].Miner.MiningSetup.MiningPairs) { if (mPair.Algorithm is DualAlgorithm algo && algo.TuningEnabled && algo.MostProfitableIntensity != algo.CurrentIntensity) { dcriChanged = true; break; } } // if algoType valid and different from currently running update if (newAlgoType != _runningGroupMiners[runningGroupKey].DualAlgorithmType || dcriChanged) { // remove current one and schedule to stop mining toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; // create new one TODO check if DaggerHashimoto GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNvidiaPaused != null && _ethminerNvidiaPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNvidiaPaused; } if (_ethminerAmdPaused != null && _ethminerAmdPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAmdPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } else { noChangeGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } } } } // check brand new foreach (var kvp in newGroupedMiningPairs) { var key = kvp.Key; var miningPairs = kvp.Value; if (_runningGroupMiners.ContainsKey(key) == false) { var newGroupMiner = new GroupMiner(miningPairs, key); toRunNewGroupMiners[key] = newGroupMiner; } } if ((toStopGroupMiners.Values.Count > 0) || (toRunNewGroupMiners.Values.Count > 0)) { var stringBuilderPreviousAlgo = new StringBuilder(); var stringBuilderCurrentAlgo = new StringBuilder(); var stringBuilderNoChangeAlgo = new StringBuilder(); // stop old miners foreach (var toStop in toStopGroupMiners.Values) { stringBuilderPreviousAlgo.Append($"{toStop.DevicesInfoString}: {toStop.AlgorithmType}, "); toStop.Stop(); _runningGroupMiners.Remove(toStop.Key); // TODO check if daggerHashimoto and save if (toStop.AlgorithmType == AlgorithmType.DaggerHashimoto) { if (toStop.DeviceType == DeviceType.NVIDIA) { _ethminerNvidiaPaused = toStop; } else if (toStop.DeviceType == DeviceType.AMD) { _ethminerAmdPaused = toStop; } } } // start new miners foreach (var toStart in toRunNewGroupMiners.Values) { stringBuilderCurrentAlgo.Append($"{toStart.DevicesInfoString}: {toStart.AlgorithmType}, "); toStart.Start(_miningLocation, _btcAdress, _worker); _runningGroupMiners[toStart.Key] = toStart; } // which miners dosen't change foreach (var noChange in noChangeGroupMiners.Values) { stringBuilderNoChangeAlgo.Append($"{noChange.DevicesInfoString}: {noChange.AlgorithmType}, "); } if (stringBuilderPreviousAlgo.Length > 0) { Helpers.ConsolePrint(Tag, $"Stop Mining: {stringBuilderPreviousAlgo}"); } if (stringBuilderCurrentAlgo.Length > 0) { Helpers.ConsolePrint(Tag, $"Now Mining : {stringBuilderCurrentAlgo}"); } if (stringBuilderNoChangeAlgo.Length > 0) { Helpers.ConsolePrint(Tag, $"No change : {stringBuilderNoChangeAlgo}"); } } } // stats quick fix code //if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { //await MinerStatsCheck(); //} _mainFormRatesComunication?.ForceMinerStatsUpdate(); }
/// <summary> /// SwichMostProfitable should check the best combination for most profit. /// Calculate profit for each supported algorithm per device group. /// Build from ground up compatible devices and algorithms. /// See #region Groupping logic /// Device groups are CPU, AMD_OpenCL and NVIDIA CUDA SM.x.x. /// NVIDIA SMx.x should be paired separately except for daggerhashimoto. /// </summary> /// <param name="NiceHashData"></param> public void SwichMostProfitableGroupUpMethod(Dictionary <AlgorithmType, NiceHashSMA> NiceHashData) { var devProfits = GetEnabledDeviceProifitDictionary(_perDeviceSpeedDictionary, NiceHashData); #if (SWITCH_TESTING) SwitchTesting.Instance.SetNext(ref devProfits, _enabledDevices); #endif double CurrentProfit = 0.0d; // calculate most profitable algorithm per enabled device foreach (var cdev in _enabledDevices) { var curDevProfits = devProfits[cdev.UUID]; double maxProfit = double.MinValue; AlgorithmType maxAlgorithmTypeKey = AlgorithmType.NONE; var algorithmSettings = cdev.DeviceBenchmarkConfig.AlgorithmSettings; foreach (var kvpTypeProfit in curDevProfits) { if (algorithmSettings.ContainsKey(kvpTypeProfit.Key) && !algorithmSettings[kvpTypeProfit.Key].Skip && kvpTypeProfit.Value > 0.0d && maxProfit < kvpTypeProfit.Value) { // extra check if current device can't handle dagger if (AlgorithmType.DaggerHashimoto == kvpTypeProfit.Key && !cdev.IsEtherumCapale) { continue; } maxProfit = kvpTypeProfit.Value; maxAlgorithmTypeKey = kvpTypeProfit.Key; } } if (maxAlgorithmTypeKey == AlgorithmType.NONE) { cdev.MostProfitableAlgorithm = null; } else { cdev.MostProfitableAlgorithm = algorithmSettings[maxAlgorithmTypeKey]; // add most profitable to cumulative profit CurrentProfit += maxProfit; } } // now if profitable check // TODO FOR NOW USD ONLY var currentProfitUSD = (CurrentProfit * Globals.BitcoinRate); Helpers.ConsolePrint(TAG, "Current Global profit: " + currentProfitUSD.ToString("F8") + " USD/Day"); if (ConfigManager.Instance.GeneralConfig.MinimumProfit > 0 && currentProfitUSD < ConfigManager.Instance.GeneralConfig.MinimumProfit) { IsProfitable = false; IsCurrentlyIdle = true; _mainFormRatesComunication.ShowNotProfitable(); // return don't group StopAllMinersNonProfitable(); Helpers.ConsolePrint(TAG, "Current Global profit: NOT PROFITABLE MinProfit " + ConfigManager.Instance.GeneralConfig.MinimumProfit.ToString("F8") + " USD/Day"); return; } else { IsProfitable = true; IsCurrentlyIdle = false; _mainFormRatesComunication.HideNotProfitable(); string profitabilityInfo = ConfigManager.Instance.GeneralConfig.MinimumProfit == 0 ? "mine always regardless of profit" : ConfigManager.Instance.GeneralConfig.MinimumProfit.ToString("F8") + " USD/Day"; Helpers.ConsolePrint(TAG, "Current Global profit: IS PROFITABLE MinProfit " + profitabilityInfo); } // group devices with same supported algorithms _previousAllGroupedDevices = _currentAllGroupedDevices; _currentAllGroupedDevices = new AllGroupedDevices(); Dictionary <GroupedDevices, Algorithm> newGroupAndAlgorithm = new Dictionary <GroupedDevices, Algorithm>(); for (int first = 0; first < _enabledDevices.Count; ++first) { var firstDev = _enabledDevices[first]; // skip if no algorithm is profitable if (firstDev.MostProfitableAlgorithm == null) { Helpers.ConsolePrint("SwichMostProfitableGroupUpMethod", String.Format("Device {0}, MostProfitableAlgorithm == null", firstDev.Name)); continue; } // check if is in group bool isInGroup = false; foreach (var groupedDevices in _currentAllGroupedDevices) { if (groupedDevices.Contains(firstDev.UUID)) { isInGroup = true; break; } } if (isInGroup) { continue; } var newGroup = new GroupedDevices(); newGroup.Add(firstDev.UUID); for (int second = first + 1; second < _enabledDevices.Count; ++second) { var secondDev = _enabledDevices[second]; // first check if second device has profitable algorithm if (secondDev.MostProfitableAlgorithm != null) { // check if we should group if (IsDaggerAndSameComputePlatform(firstDev, secondDev) || IsGroupBinaryAndAlgorithmSame(firstDev, secondDev)) { newGroup.Add(secondDev.UUID); } } } _currentAllGroupedDevices.Add(newGroup); newGroupAndAlgorithm.Add(newGroup, firstDev.MostProfitableAlgorithm); } // stop groupes that aren't in current group devices foreach (var curPrevGroup in _previousAllGroupedDevices) { var curPrevGroupKey = CalcGroupedDevicesKey(curPrevGroup); bool contains = false; foreach (var curCheckGroup in _currentAllGroupedDevices) { var curCheckGroupKey = CalcGroupedDevicesKey(curCheckGroup); if (curPrevGroupKey == curCheckGroupKey) { contains = true; break; } } if (!contains) { _groupedDevicesMiners[curPrevGroupKey].Stop(); } } // switch to newGroupAndAlgorithm most profitable algorithm foreach (var kvpGroupAlgorithm in newGroupAndAlgorithm) { var group = kvpGroupAlgorithm.Key; var algorithm = kvpGroupAlgorithm.Value; GroupMiners currentGroupMiners; // try find if it doesn't exist create new string groupStringKey = CalcGroupedDevicesKey(group); if (!_groupedDevicesMiners.TryGetValue(groupStringKey, out currentGroupMiners)) { currentGroupMiners = new GroupMiners(group); _groupedDevicesMiners.Add(groupStringKey, currentGroupMiners); } currentGroupMiners.StartAlgorihtm(algorithm, _miningLocation, _workerBtcStringWorker); } // stats quick fix code if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { MinerStatsCheck(NiceHashData); } }
public bool StartInitialize(IMainFormRatesComunication mainFormRatesComunication, string miningLocation, string worker, string btcAdress) { _mainFormRatesComunication = mainFormRatesComunication; _miningLocation = miningLocation; _worker = worker; _btcAdress = btcAdress; if (_worker.Length > 0) { _workerBtcStringWorker = _btcAdress + "." + _worker; } else { _workerBtcStringWorker = _btcAdress; } _perDeviceSpeedDictionary = GetEnabledDeviceTypeSpeeds(); //_groupedDevicesMiners = new Dictionary<GroupedDevices, GroupMiners>(); _groupedDevicesMiners = new Dictionary <string, GroupMiners>(); _enabledDevices = new List <ComputeDevice>(); _currentAllGroupedDevices = new AllGroupedDevices(); // assume profitable IsProfitable = true; // this checks if there are enabled devices and enabled algorithms bool isMiningEnabled = false; foreach (var cdev in ComputeDevice.AllAvaliableDevices) { if (cdev.Enabled) { _enabledDevices.Add(cdev); // check if in CPU group and add the saved CPU miners if (cdev.DeviceGroupType == DeviceGroupType.CPU) { GroupedDevices gdevs = new GroupedDevices(); gdevs.Add(cdev.UUID); cpuminer miner = _cpuMiners[cdev.Group]; CpuGroupMiner cpuGroupMiner = new CpuGroupMiner(gdevs, miner); _groupedDevicesMiners.Add(CalcGroupedDevicesKey(gdevs), cpuGroupMiner); } // check if any algorithm enabled if (!isMiningEnabled) { foreach (var algorithm in cdev.DeviceBenchmarkConfig.AlgorithmSettings) { if (!algorithm.Value.Skip) { isMiningEnabled = true; break; } } } } } if (isMiningEnabled) { _preventSleepTimer.Start(); } IsCurrentlyIdle = !isMiningEnabled; return(isMiningEnabled); }
public void SwichMostProfitableGroupUpMethod(Dictionary <AlgorithmType, NiceHashSMA> NiceHashData, bool log = true) { #if (SWITCH_TESTING) MiningDevice.SetNextTest(); #endif List <MiningPair> profitableDevices = new List <MiningPair>(); double CurrentProfit = 0.0d; foreach (var device in _miningDevices) { // calculate profits device.CalculateProfits(NiceHashData); // check if device has profitable algo if (device.HasProfitableAlgo()) { profitableDevices.Add(device.GetMostProfitablePair()); CurrentProfit += device.GetCurrentMostProfitValue; } } // print profit statuses if (log) { StringBuilder stringBuilderFull = new StringBuilder(); stringBuilderFull.AppendLine("Current device profits:"); foreach (var device in _miningDevices) { StringBuilder stringBuilderDevice = new StringBuilder(); stringBuilderDevice.AppendLine(String.Format("\tProfits for {0} ({1}):", device.Device.UUID, device.Device.Name)); foreach (var algo in device.Algorithms) { stringBuilderDevice.AppendLine(String.Format("\t\tPROFIT = {0}\t(SPEED = {1}\t\t| NHSMA = {2})\t[{3}]", algo.Value.CurrentProfit.ToString(DOUBLE_FORMAT), // Profit algo.Value.AvaragedSpeed, // Speed algo.Value.CurNhmSMADataVal, // NiceHashData AlgorithmNiceHashNames.GetName(algo.Key) // Name )); } // most profitable stringBuilderDevice.AppendLine(String.Format("\t\tMOST PROFITABLE ALGO: {0}, PROFIT: {1}", AlgorithmNiceHashNames.GetName(device.MostProfitableKey), device.GetCurrentMostProfitValue.ToString(DOUBLE_FORMAT))); stringBuilderFull.AppendLine(stringBuilderDevice.ToString()); } Helpers.ConsolePrint(TAG, stringBuilderFull.ToString()); } // check if should mine if (CheckIfShouldMine(CurrentProfit, log) == false) { return; } Dictionary <string, List <MiningPair> > newGroupedMiningPairs = new Dictionary <string, List <MiningPair> >(); // group devices with same supported algorithms { var currentGroupedDevices = new List <GroupedDevices>(); for (int first = 0; first < profitableDevices.Count; ++first) { var firstDev = profitableDevices[first].Device; // check if is in group bool isInGroup = false; foreach (var groupedDevices in currentGroupedDevices) { if (groupedDevices.Contains(firstDev.UUID)) { isInGroup = true; break; } } // if device is not in any group create new group and check if other device should group if (isInGroup == false) { var newGroup = new GroupedDevices(); var miningPairs = new List <MiningPair>() { profitableDevices[first] }; newGroup.Add(firstDev.UUID); for (int second = first + 1; second < profitableDevices.Count; ++second) { // check if we should group var firstPair = profitableDevices[first]; var secondPair = profitableDevices[second]; if (GroupingLogic.ShouldGroup(firstPair, secondPair)) { var secondDev = profitableDevices[second].Device; newGroup.Add(secondDev.UUID); miningPairs.Add(profitableDevices[second]); } } currentGroupedDevices.Add(newGroup); newGroupedMiningPairs[CalcGroupedDevicesKey(newGroup)] = miningPairs; } } } //bool IsMinerStatsCheckUpdate = false; { // check which groupMiners should be stopped and which ones should be started and which to keep running Dictionary <string, GroupMiner> toStopGroupMiners = new Dictionary <string, GroupMiner>(); Dictionary <string, GroupMiner> toRunNewGroupMiners = new Dictionary <string, GroupMiner>(); // check what to stop/update foreach (string runningGroupKey in _runningGroupMiners.Keys) { if (newGroupedMiningPairs.ContainsKey(runningGroupKey) == false) { // runningGroupKey not in new group definately needs to be stopped and removed from curently running toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } else { // runningGroupKey is contained but needs to check if mining algorithm is changed var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); if (newAlgoType != AlgorithmType.NONE && newAlgoType != AlgorithmType.INVALID) { // if algoType valid and different from currently running update if (newAlgoType != _runningGroupMiners[runningGroupKey].AlgorithmType) { // remove current one and schedule to stop mining toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; // create new one TODO check if DaggerHashimoto GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } } } } // check brand new foreach (var kvp in newGroupedMiningPairs) { var key = kvp.Key; var miningPairs = kvp.Value; if (_runningGroupMiners.ContainsKey(key) == false) { GroupMiner newGroupMiner = new GroupMiner(miningPairs, key); toRunNewGroupMiners[key] = newGroupMiner; } } // stop old miners foreach (var toStop in toStopGroupMiners.Values) { toStop.Stop(); _runningGroupMiners.Remove(toStop.Key); // TODO check if daggerHashimoto and save if (toStop.AlgorithmType == AlgorithmType.DaggerHashimoto) { if (toStop.DeviceType == DeviceType.NVIDIA) { _ethminerNVIDIAPaused = toStop; } else if (toStop.DeviceType == DeviceType.AMD) { _ethminerAMDPaused = toStop; } } } // start new miners foreach (var toStart in toRunNewGroupMiners.Values) { toStart.Start(_miningLocation, _btcAdress, _worker); _runningGroupMiners[toStart.Key] = toStart; } } // stats quick fix code //if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { MinerStatsCheck(NiceHashData); //} }
public async Task SwichMostProfitableGroupUpMethod(Dictionary <AlgorithmType, CryptoMiner937API> CryptoMiner937Data, bool log = false) { #if (SWITCH_TESTING) MiningDevice.SetNextTest(); #endif List <MiningPair> profitableDevices = new List <MiningPair>(); double CurrentProfit = 0.0d; double PrevStateProfit = 0.0d; foreach (var device in _miningDevices) { // calculate profits device.CalculateProfits(CryptoMiner937Data); // check if device has profitable algo if (device.HasProfitableAlgo()) { profitableDevices.Add(device.GetMostProfitablePair()); CurrentProfit += device.GetCurrentMostProfitValue; PrevStateProfit += device.GetPrevMostProfitValue; } } // print profit statuses if (log) { StringBuilder stringBuilderFull = new StringBuilder(); stringBuilderFull.AppendLine("Current device profits:"); foreach (var device in _miningDevices) { StringBuilder stringBuilderDevice = new StringBuilder(); stringBuilderDevice.AppendLine(String.Format("\tProfits for {0} ({1}):", device.Device.UUID, device.Device.GetFullName())); foreach (var algo in device.Algorithms) { stringBuilderDevice.AppendLine(String.Format("\t\tPROFIT = {0}\t(SPEED = {1}\t\t| NHSMA = {2})\t[{3}]", algo.CurrentProfit.ToString(DOUBLE_FORMAT), // Profit algo.AvaragedSpeed + (algo.IsDual() ? "/" + algo.SecondaryAveragedSpeed : ""), // Speed algo.CurNhmSMADataVal + (algo.IsDual() ? "/" + algo.SecondaryCurNhmSMADataVal : ""), // CryptoMiner937Data algo.AlgorithmStringID // Name )); } // most profitable stringBuilderDevice.AppendLine(String.Format("\t\tMOST PROFITABLE ALGO: {0}, PROFIT: {1}", device.GetMostProfitableString(), device.GetCurrentMostProfitValue.ToString(DOUBLE_FORMAT))); stringBuilderFull.AppendLine(stringBuilderDevice.ToString()); } Helpers.ConsolePrint(TAG, stringBuilderFull.ToString()); } // check if should mine // Only check if profitable inside this method when getting SMA data, cheching during mining is not reliable if (CheckIfShouldMine(CurrentProfit, log) == false) { foreach (var device in _miningDevices) { device.SetNotMining(); } return; } // check profit threshold Helpers.ConsolePrint(TAG, String.Format("PrevStateProfit {0}, CurrentProfit {1}", PrevStateProfit, CurrentProfit)); if (PrevStateProfit > 0 && CurrentProfit > 0) { double a = Math.Max(PrevStateProfit, CurrentProfit); double b = Math.Min(PrevStateProfit, CurrentProfit); //double percDiff = Math.Abs((PrevStateProfit / CurrentProfit) - 1); double percDiff = ((a - b)) / b; if (percDiff < ConfigManager.GeneralConfig.SwitchProfitabilityThreshold) { // don't switch //Helpers.ConsolePrint(TAG, String.Format("Will NOT switch profit diff is {0}, current threshold {1}", percDiff, ConfigManager.GeneralConfig.SwitchProfitabilityThreshold)); // RESTORE OLD PROFITS STATE foreach (var device in _miningDevices) { device.RestoreOldProfitsState(); } if (!SHOULD_START_DONATING) { return; } } else { Helpers.ConsolePrint(TAG, String.Format("Will SWITCH profit diff is {0}, current threshold {1}", percDiff, ConfigManager.GeneralConfig.SwitchProfitabilityThreshold)); } } Helpers.ConsolePrint("Monitoring", "If enabled here I would submit Monitoring data to the server"); if (ConfigManager.GeneralConfig.monitoring == true) { //Run monitoring command here var monversion = "Hash-Kings Miner V" + Application.ProductVersion; #pragma warning disable CS0219 // The variable 'monstatus' is assigned but its value is never used var monstatus = "Running"; #pragma warning restore CS0219 // The variable 'monstatus' is assigned but its value is never used #pragma warning disable CS0219 // The variable 'monrunningminers' is assigned but its value is never used var monrunningminers = "" /*Runningminers go here*/; #pragma warning restore CS0219 // The variable 'monrunningminers' is assigned but its value is never used var monserver = ConfigManager.GeneralConfig.MonServerurl + "/api/report.php"; var request = (HttpWebRequest)WebRequest.Create(monserver); var postData = ""; /* fetch last command line for each miner * Do this for each mining group*/ foreach (var cdev in ComputeDeviceManager.Avaliable.AllAvaliableDevices) { if (cdev.Enabled) { postData += "Name" + Uri.EscapeDataString("Miner Name"); postData += "Path" + Uri.EscapeDataString("miner Path goes here"); postData += "Type" + Uri.EscapeDataString("Type of card EX. AMD"); postData += "Algorithm" + Uri.EscapeDataString("Current mining Algorithm"); postData += "Pool" + Uri.EscapeDataString("Pool Goes Here"); postData += "CurrentSpeed" + Uri.EscapeDataString("Actual hashrate goes here"); postData += "EstimatedSpeed" + Uri.EscapeDataString("Benchmark hashrate Goes Here"); postData += "Profit" + Uri.EscapeDataString("group profitability goes here"); } ; } /* * * Convert above data to Json * Fetch Profit to Variable * $Profit = [string]([Math]::Round(($data | Measure-Object Profit -Sum).Sum, 8)) * Send the request * $Body = @{user = $Config.MonitoringUser; worker = $Config.WorkerName; version = $Version; status = $Status; profit = $Profit; data = $DataJSON} * Try { * $Response = Invoke-RestMethod -Uri "$($Config.MonitoringServer)/api/report.php" -Method Post -Body $Body -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop * Helpers.ConsolePrint("Monitoring", "Reporting status to server..." + $Server responce here" * } * Catch { * Helpers.ConsolePrint("Monitoring", "Unable to send status to " monserver}*/ var data = Encoding.ASCII.GetBytes(postData); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); } // group new miners Dictionary <string, List <MiningPair> > newGroupedMiningPairs = new Dictionary <string, List <MiningPair> >(); // group devices with same supported algorithms { var currentGroupedDevices = new List <GroupedDevices>(); for (int first = 0; first < profitableDevices.Count; ++first) { var firstDev = profitableDevices[first].Device; // check if is in group bool isInGroup = false; foreach (var groupedDevices in currentGroupedDevices) { if (groupedDevices.Contains(firstDev.UUID)) { isInGroup = true; break; } } // if device is not in any group create new group and check if other device should group if (isInGroup == false) { var newGroup = new GroupedDevices(); var miningPairs = new List <MiningPair>() { profitableDevices[first] }; newGroup.Add(firstDev.UUID); for (int second = first + 1; second < profitableDevices.Count; ++second) { // check if we should group var firstPair = profitableDevices[first]; var secondPair = profitableDevices[second]; if (GroupingLogic.ShouldGroup(firstPair, secondPair)) { var secondDev = profitableDevices[second].Device; newGroup.Add(secondDev.UUID); miningPairs.Add(profitableDevices[second]); } } currentGroupedDevices.Add(newGroup); newGroupedMiningPairs[CalcGroupedDevicesKey(newGroup)] = miningPairs; } } } //bool IsMinerStatsCheckUpdate = false; { // check which groupMiners should be stopped and which ones should be started and which to keep running Dictionary <string, GroupMiner> toStopGroupMiners = new Dictionary <string, GroupMiner>(); Dictionary <string, GroupMiner> toRunNewGroupMiners = new Dictionary <string, GroupMiner>(); Dictionary <string, GroupMiner> noChangeGroupMiners = new Dictionary <string, GroupMiner>(); if (MiningSession.SHOULD_START_DONATING) { MiningSession.IS_DONATING = true; } // check what to stop/update int count = _runningGroupMiners.Keys.Count; int it = 0; // + " Mining For : " +(MiningSession.DONATION_SESSION ? "Developer" : "User") foreach (string runningGroupKey in _runningGroupMiners.Keys) { it++; if (newGroupedMiningPairs.ContainsKey(runningGroupKey) == false) { // runningGroupKey not in new group definately needs to be stopped and removed from curently running toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } // If we need to start donating, stop everything else if (MiningSession.IS_DONATING && !MiningSession.DONATION_SESSION) { if (it == count) { MiningSession.DONATION_SESSION = true; } toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; Helpers.ConsolePrint(TAG, "STARTING - DEV_FEE - Mining Dev-Fee for 24 Minutes."); var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } else if (MiningSession.IS_DONATING && MiningSession.DONATION_SESSION && MiningSession.SHOULD_STOP_DONATING) { if (it == count) { MiningSession.DONATION_SESSION = false; MiningSession.IS_DONATING = false; MiningSession.DonationStart = MiningSession.DonationStart.Add(MiningSession.DonateEvery); } toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; Helpers.ConsolePrint(TAG, "STOPPING - DEV_FEE - Next Dev-Fee Mining will start in 24 Hours."); var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } else { MiningSession.DONATION_SESSION = false; MiningSession.IS_DONATING = false; // runningGroupKey is contained but needs to check if mining algorithm is changed var miningPairs = newGroupedMiningPairs[runningGroupKey]; var newAlgoType = GetMinerPairAlgorithmType(miningPairs); if (newAlgoType != AlgorithmType.NONE && newAlgoType != AlgorithmType.INVALID) { // if algoType valid and different from currently running update if (newAlgoType != _runningGroupMiners[runningGroupKey].DualAlgorithmType) { // remove current one and schedule to stop mining toStopGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; // create new one TODO check if DaggerHashimoto GroupMiner newGroupMiner = null; if (newAlgoType == AlgorithmType.DaggerHashimoto) { if (_ethminerNVIDIAPaused != null && _ethminerNVIDIAPaused.Key == runningGroupKey) { newGroupMiner = _ethminerNVIDIAPaused; } if (_ethminerAMDPaused != null && _ethminerAMDPaused.Key == runningGroupKey) { newGroupMiner = _ethminerAMDPaused; } } if (newGroupMiner == null) { newGroupMiner = new GroupMiner(miningPairs, runningGroupKey); } toRunNewGroupMiners[runningGroupKey] = newGroupMiner; } else { noChangeGroupMiners[runningGroupKey] = _runningGroupMiners[runningGroupKey]; } } } } // check brand new foreach (var kvp in newGroupedMiningPairs) { var key = kvp.Key; var miningPairs = kvp.Value; if (_runningGroupMiners.ContainsKey(key) == false) { GroupMiner newGroupMiner = new GroupMiner(miningPairs, key); toRunNewGroupMiners[key] = newGroupMiner; } } if ((toStopGroupMiners.Values.Count > 0) || (toRunNewGroupMiners.Values.Count > 0)) { StringBuilder stringBuilderPreviousAlgo = new StringBuilder(); StringBuilder stringBuilderCurrentAlgo = new StringBuilder(); StringBuilder stringBuilderNoChangeAlgo = new StringBuilder(); // stop old miners foreach (var toStop in toStopGroupMiners.Values) { stringBuilderPreviousAlgo.Append(String.Format("{0}: {1}, ", toStop.DevicesInfoString, toStop.AlgorithmType)); toStop.Stop(); _runningGroupMiners.Remove(toStop.Key); // TODO check if daggerHashimoto and save if (toStop.AlgorithmType == AlgorithmType.DaggerHashimoto) { if (toStop.DeviceType == DeviceType.NVIDIA) { _ethminerNVIDIAPaused = toStop; } else if (toStop.DeviceType == DeviceType.AMD) { _ethminerAMDPaused = toStop; } } } // start new miners foreach (var toStart in toRunNewGroupMiners.Values) { stringBuilderCurrentAlgo.Append(String.Format("{0}: {1}, ", toStart.DevicesInfoString, toStart.AlgorithmType)); toStart.Start(_miningLocation, _btcAddress, _worker); _runningGroupMiners[toStart.Key] = toStart; } // which miners dosen't change foreach (var noChange in noChangeGroupMiners.Values) { stringBuilderNoChangeAlgo.Append(String.Format("{0}: {1}, ", noChange.DevicesInfoString, noChange.AlgorithmType)); } if (stringBuilderPreviousAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("Stop Mining: {0}", stringBuilderPreviousAlgo.ToString())); } if (stringBuilderCurrentAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("Now Mining : {0}", stringBuilderCurrentAlgo.ToString())); } if (stringBuilderNoChangeAlgo.Length > 0) { Helpers.ConsolePrint(TAG, String.Format("No change : {0}", stringBuilderNoChangeAlgo.ToString())); } } } // stats quick fix code //if (_currentAllGroupedDevices.Count != _previousAllGroupedDevices.Count) { await MinerStatsCheck(CryptoMiner937Data); //} }