コード例 #1
0
        private async void SwitchManuallyCommand(object obj)
        {
            ProfitTablesEnabled = true;
            if (ProfitTables.Tables == null || ProfitTables.Tables.Count == 0)
            {
                ProfitTables.Tables.Clear();
                for (var i = 0; i < Workers.WorkerList.Count; i++)
                {
                    var worker = Workers.WorkerList[i];

                    if (worker.Query)
                    {
                        var newTable = new ProfitTable
                        {
                            Name        = worker.Name,
                            Index       = i + 1,
                            ThisPC      = Helpers.ListContainsThisPC(worker.Computers),
                            Description = worker.Description,
                            Computers   = new ObservableCollection <Computer>(),
                            ProfitList  = new List <ProfitTableRow>()
                        };
                        foreach (var pc in worker.Computers)
                        {
                            newTable.Computers.Add(new Computer {
                                Name = pc, IsExpanded = true
                            });
                        }
                        foreach (var ct in worker.CoinList)
                        {
                            newTable.ProfitList.Add(new ProfitTableRow
                            {
                                Name      = ct.FullName,
                                Symbol    = ct.FullSymbol,
                                Algorithm = ct.FullAlgorithm,
                                Hashrate  = ct.FullHashrate,
                                Path      = ct.Path,
                                Arguments = ct.Arguments
                            });
                        }
                        var first = newTable.ProfitList.FirstOrDefault();
                        if (first != null)
                        {
                            first.ManualSwitch = true;
                        }

                        //Show the topmost coin as the new coin in Computers list
                        newTable.HookPropertyChanched();
                        newTable.Row_PropertyChanged(newTable.ProfitList.FirstOrDefault(), new PropertyChangedEventArgs("ManualSwitch"));

                        ProfitTables.Tables.Add(newTable);
                    }
                }

                ScanLan.RaiseCanExecuteChanged();
                ScanLanCommand(null);
                return;
            }

            Computer thisPc   = null;
            var      toDoList = new ObservableCollection <ProfitTable>();

            bool noComputerIsOnline = true;

            var negativeProfitCoinLsit = new List <(string worker, string coin, string profit)>();
            var alreadyMiningPcLsit    = new List <(string worker, string pc, string coin)>();
            var lessProfitablePcLsit   = new List <(string worker, string pc, string currentCoin, string switchCoin)>();

            foreach (var table in ProfitTables.Tables)
            {
                var selectedCoinRow = table.ProfitList.FirstOrDefault(x => x.ManualSwitch);

                var newTable = new ProfitTable
                {
                    Name       = table.Name,
                    ProfitList = new List <ProfitTableRow> {
                        selectedCoinRow
                    },
                    Computers = new ObservableCollection <Computer>()
                };

                bool switchChecked = false;

                foreach (var pc in table.Computers)
                {
                    if (pc.OnlineStatus == Computer.OperationStatus.Success)
                    {
                        noComputerIsOnline = false;
                    }

                    if (pc.Switch)
                    {
                        switchChecked = true;
                    }

                    if (pc.OnlineStatus == Computer.OperationStatus.Success && (pc.Switch || pc.Restart))
                    {
                        // Detect empty path
                        if (pc.Switch && (selectedCoinRow.Path == null || selectedCoinRow.Path == string.Empty))
                        {
                            MessageBox.Show($"The selected coin {selectedCoinRow.NameAndSymbol} in {table.Name} has the Path field empty. Define a path to an executable and try again.", "Path cannot be empty", MessageBoxButton.OK, MessageBoxImage.Error);
                            OnSwitchManuallyExit();
                            return;
                        }

                        var fullName = $"{pc.CurrentCoinName} ({pc.CurrentCoinSymbol})";
                        // Detect that the SwitchCoin is already mined
                        if (pc.Switch && selectedCoinRow.Name == pc.CurrentCoinName)
                        {
                            alreadyMiningPcLsit.Add((table.Name, pc.Name, fullName));
                        }

                        // Detect that the SwitchCoin is less profitable that the currently mined one
                        var currentlyMinedCoinRow = table.ProfitList.FirstOrDefault(x => x.Name == pc.CurrentCoinName);
                        if (pc.Switch && currentlyMinedCoinRow != null && currentlyMinedCoinRow.ProfitDay > selectedCoinRow.ProfitDay)
                        {
                            lessProfitablePcLsit.Add((table.Name, pc.Name, fullName, selectedCoinRow.NameAndSymbol));
                        }

                        var computer = new Computer
                        {
                            Name              = pc.Name,
                            CurrentCoinName   = pc.CurrentCoinName,
                            CurrentCoinSymbol = pc.CurrentCoinSymbol,
                            Switch            = pc.Switch,
                            Restart           = pc.Restart,
                            SwitchStatus      = Computer.OperationStatus.Indeterminate,
                            RestartStatus     = Computer.OperationStatus.Indeterminate,
                        };
                        if (computer.IsThisPc && thisPc == null)
                        {
                            thisPc = computer;
                        }
                        newTable.Computers.Add(computer);
                    }
                }

                // Detect negative profit
                if (switchChecked && selectedCoinRow.ProfitDay <= 0)
                {
                    negativeProfitCoinLsit.Add((table.Name, selectedCoinRow.NameAndSymbol, selectedCoinRow.ProfitDay.ToString("N2")));
                }

                if (newTable.Computers.Count != 0)
                {
                    toDoList.Add(newTable);
                }
            }

            if (toDoList.Count == 0)
            {
                string message = null;
                if (noComputerIsOnline)
                {
                    message = "There are no computers online.";
                }
                else
                {
                    message = "There are some computers online but none is checked either for Switch or Restart.";
                }

                MessageBox.Show(message, "Nothing to do", MessageBoxButton.OK, MessageBoxImage.Information);
                OnSwitchManuallyExit();
                return;
            }

            // Disable Switch button. Call OnSwitchManuallyExit before every return to re-enable it.
            SwitchManuallyIsInProgress = true;

            // Check if localhost is among the pcList machines and it has a background switch job running
            if (SwitchIsInProgress && thisPc != null)
            {
                var result = MessageBox.Show($"An unfinished switching task is currently running in the background. It may overwrite the results of this operation on {thisPc.Name} when it is done. Stop the background job and switch anyway?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    SwitchCancelSource.Cancel();
                    while (SwitchIsInProgress)
                    {
                        await Task.Delay(100);
                    }
                }
                else
                {
                    OnSwitchManuallyExit();
                    return;
                }
            }

            // Warn if any issues detected
            if (negativeProfitCoinLsit.Count != 0 || alreadyMiningPcLsit.Count != 0 || lessProfitablePcLsit.Count != 0)
            {
                FlowDocument document = new FlowDocument();
                int          cnt      = negativeProfitCoinLsit.Count;
                if (cnt != 0)
                {
                    var paragraph = new Paragraph(new Run("The following selected coins have zero or negative profit:\r\n"));
                    for (int i = 0; i < cnt; i++)
                    {
                        var entry  = negativeProfitCoinLsit[i];
                        Run worker = new Run($"{entry.worker}: ");
                        worker.FontWeight = FontWeights.Bold;
                        paragraph.Inlines.Add(worker);
                        paragraph.Inlines.Add($"The daily profit of {entry.coin} is {entry.profit}.");
                        if (i < cnt - 1)
                        {
                            paragraph.Inlines.Add("\r\n");
                        }
                    }

                    document.Blocks.Add(paragraph);
                }
                cnt = alreadyMiningPcLsit.Count;
                if (alreadyMiningPcLsit.Count != 0)
                {
                    var paragraph = new Paragraph(new Run("The following computers are already mining the selected coin:\r\n"));
                    document.Blocks.Add(paragraph);
                    for (int i = 0; i < cnt; i++)
                    {
                        var entry  = alreadyMiningPcLsit[i];
                        Run worker = new Run($"{entry.worker}: ");
                        worker.FontWeight = FontWeights.Bold;
                        paragraph.Inlines.Add(worker);
                        paragraph.Inlines.Add($"{entry.pc} is already mining {entry.coin}.");
                        if (i < cnt - 1)
                        {
                            paragraph.Inlines.Add("\r\n");
                        }
                    }

                    document.Blocks.Add(paragraph);
                }
                cnt = lessProfitablePcLsit.Count;
                if (lessProfitablePcLsit.Count != 0)
                {
                    var paragraph = new Paragraph(new Run("The following computers are mining a coin that is more profitable than the one you've selected:\r\n"));
                    document.Blocks.Add(paragraph);
                    for (int i = 0; i < cnt; i++)
                    {
                        var entry  = lessProfitablePcLsit[i];
                        Run worker = new Run($"{entry.worker}: ");
                        worker.FontWeight = FontWeights.Bold;
                        paragraph.Inlines.Add(worker);
                        paragraph.Inlines.Add($"{entry.pc} is mining {entry.currentCoin} which is more profitable than {entry.switchCoin}.");
                        if (i < cnt - 1)
                        {
                            paragraph.Inlines.Add("\r\n");
                        }
                    }

                    document.Blocks.Add(paragraph);
                }

                var reportWindow = new Report();
                reportWindow.RichTextBox.Document = document;
                reportWindow.Title       = "Switch Inspector";
                reportWindow.Header.Text = $"{Constants.AppName} has detected some issues:";
                reportWindow.Footer.Text = "Press 'OK' to ignore warnings and proceed or 'Cancel' to abort switching:";

                var reportDialogResult = reportWindow.ShowDialog();
                if (reportDialogResult == false)
                {
                    OnSwitchManuallyExit();
                    return;
                }
            }

            // Show Switch window

            var switchWindow = new SwitchWindow();
            var vm           = new SwitchWindowVM(toDoList);

            switchWindow.DataContext = vm;
            var switchDialogResult = switchWindow.ShowDialog();

            if (vm.SwitchIsInProgress && vm.ManualSwitchCancelSource != null)
            {
                vm.ManualSwitchCancelSource.Cancel();
            }
            if (vm.SwitchIsInProgress || (vm.SwitchIsFinished && switchDialogResult == true))
            {
                ScanLanCommand(null);
            }

            OnSwitchManuallyExit();
        }
コード例 #2
0
ファイル: ViewModel.cs プロジェクト: xeddmc/MiningStation
        private async void CalculateProfitCommand(object parameter)
        {
            CalculateProfit.SetCanExecute(false);
            LoadHistoricalCharts.SetCanExecute(false);
            SwitchManually.SetCanExecute(false);

            ProfitTablesEnabled = true;

            var coinList = Workers.GetCoins(Workers.WorkerList, true);

            if (!coinList.Contains("Bitcoin"))
            {
                coinList.Add("Bitcoin");
            }

            //Update Yahoo rates if necessary
            if (WtmSettings.UseYahooRates &&
                WtmSettings.DisplayCurrency != "USD" &&
                WtmSettings.DisplayCurrency != "BTC" &&
                WtmSettingsObject.DisplayCurrencyListDate.Date != DateTime.Today)
            {
                await WtmSettings.GetYahooRates();

                if (WtmSettings.DisplayCurrencyList.Count == 2)
                {
                    BypassUndo(() => WtmSettings.UseYahooRates = false);
                    MessageBox.Show($"{Constants.AppName} could not download the list of currencies from Yahoo. Values will be displayed in USD.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }

            // Calculate mean hashrate
            var coinHashList = GetHashrates(coinList);

            // Get WTM coin data
            Dictionary <string, WtmData> wtmDataDict = null;

            (Dictionary <string, WtmData> data, WhatToMine.GetWtmCoinDataResult)wtmDataResult = (null, WhatToMine.GetWtmCoinDataResult.Fail);
            try
            {
                wtmDataResult = await WhatToMine.GetWtmCoinData(coinHashList, true);
            }
            catch (Exception ex)
            {
            }
            wtmDataDict = wtmDataResult.data;
            if (wtmDataDict == null)
            {
                CalculateProfitCommandQuit();
                return;
            }


            var    btc = wtmDataDict["Bitcoin"];
            string keyName;

            if (WtmSettings.Average24)
            {
                keyName = "exchange_rate24";
            }
            else
            {
                keyName = "exchange_rate";
            }

            string btcValue;

            btc.Json.TryGetValue(keyName, out btcValue);
            if (btcValue != null)
            {
                WtmSettings.DisplayCurrencyList["BTC"] = Helpers.StringToDecimal(btcValue);
            }
            else
            {
                MessageBox.Show("Failed to read BTC price from whattomine.com", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            // Form profit tables from wtmDataList
            ProfitTables.Tables.Clear();
            var workersChecked = Workers.WorkerList.Where(w => w.Query).ToList();
            var profitTables   = WhatToMine.CreateProfitTables(wtmDataDict, workersChecked, (decimal)Workers.PowerCost, WtmSettings);

            foreach (var table in profitTables)
            {
                ProfitTables.Tables.Add(table);
            }

            CalculateProfitCommandQuit();

            ScanLan.RaiseCanExecuteChanged();
            ScanLanCommand(null);
        }