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.GetFullName()));
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
// Only check if profitable inside this method when getting SMA data, cheching during mining is not reliable
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);
//}
}