/// <summary> /// Collect stats from WildRig and post to API /// </summary> public override async void ReportStatsAsyc() { try { // Call RPC and get response WildRigTemplate wildRigTemplate = await GetRPCResponse(); if (wildRigTemplate == null) { return; } // Map response to BPM Statistics object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat = MapRPCResponse(wildRigTemplate); if (minerMonitorStat == null) { return; } System.Threading.Thread.Sleep(8000); PostMinerMonitorStat(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error reporting stats for WildRig"); } }
/// <summary> /// Collect stats from EWBF and post to API /// </summary> public override async void ReportStatsAsyc(Guid accountId, string workerName) { try { // Call RPC and get response DSTMTemplate dstmTemplate = await GetRPCResponse(); if (dstmTemplate == null) { return; } // Map response to BPM Statistics object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat = MapRPCResponse(accountId, workerName, dstmTemplate); if (minerMonitorStat == null) { return; } System.Threading.Thread.Sleep(6000); PostMinerMonitorStat(accountId, workerName, minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error reporting stats for DSTM"); } }
/// <summary> /// Post Miner and GPU stats /// </summary> /// <returns></returns> public async void PostMinerMonitorStats(MinerMonitorStat minerMonitorStat) { string apiURL = APIConstants.APIURL + APIEndpoints.PostMinerMonitorStats; try { // Serialize our concrete class into a JSON String var stringPayload = await Task.Run(() => JsonConvert.SerializeObject(minerMonitorStat)); // Wrap our JSON inside a StringContent which then can be used by the HttpClient class var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json"); using (var httpClient = new HttpClient()) { // Do the actual request and await the response var httpResponse = await httpClient.PostAsync(apiURL, httpContent); // If the response contains content we want to read it! if (httpResponse.Content != null) { var responseContent = await httpResponse.Content.ReadAsStringAsync(); } } } catch (Exception e) { logger.Error(e, $"Error posting miner monitor stats to {apiURL}"); } }
/// <summary> /// Use OpenHardwareMonitor to add any missing data if needed /// </summary> /// <param name="stats"></param> private MinerMonitorStat SupplementMinerMonitorStatData(MinerMonitorStat stats) { // Check if any data is missing from stats if (CheckMinerMonitorStatDataMissing(stats) == true) { try { // Retrive GPU data from OpenHardwareMonitor Utils.OpenHardwareMonitor.OpenHardwareMonitor openHardwareMonitor = new Utils.OpenHardwareMonitor.OpenHardwareMonitor(); ObservableCollection <GPUSettings> gpuSettingsList = openHardwareMonitor.ScanHardware(); // Iterate through each GPUMonitorStat and add missing data foreach (GPUMonitorStat gpuMonitorStat in stats.GPUMonitorStatList) { if (gpuMonitorStat.FanSpeed == 0) { gpuMonitorStat.FanSpeed = gpuSettingsList.Where(x => x.GPUID == gpuMonitorStat.GPUID).FirstOrDefault().Fanspeed; } if (gpuMonitorStat.Temp == 0) { gpuMonitorStat.Temp = gpuSettingsList.Where(x => x.GPUID == gpuMonitorStat.GPUID).FirstOrDefault().Temp; } } } catch (Exception) { // Ignore this for now. } } return(stats); }
/// <summary> /// Map WildRig response to BPM statistics objects /// </summary> /// <param name="wildRigTemplate"></param> /// <returns></returns> private MinerMonitorStat MapRPCResponse(WildRigTemplate wildRigTemplate) { try { // Used to simulate GPU ID int gpuCounter = 0; // Create new Miner monitor stats object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; minerMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); minerMonitorStat.CoinType = this.CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; if (wildRigTemplate.hashrate.threads.Count > 0) { List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); foreach (List <int> wildRigGPU in wildRigTemplate.hashrate.threads) { // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat { AccountGuid = (Guid)Application.Current.Properties["AccountID"], WorkerName = Application.Current.Properties["WorkerName"].ToString(), CoinType = this.CoinType.ToString(), GPUID = gpuCounter, //wildRigGPU.device_id, HashRate = wildRigGPU[0], FanSpeed = 0, //(short)wildRigGPU.fan_speed, Temp = 0, //(short)wildRigGPU.temperature, Power = 0, //(short)wildRigGPU.power, HardwareType = Hardware }; // Sum up power and hashrate minerMonitorStat.Power += 0; //wildRigGPU.power; minerMonitorStat.HashRate += wildRigGPU[0]; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); // Increase GPU Counter gpuCounter++; } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; } return(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error mapping RPC Response for WildRig miner"); return(null); } }
/// <summary> /// Helper method to post miner stats back to the website /// </summary> /// <param name="stats"></param> protected void PostMinerMonitorStat(Guid accountId, string workerName, MinerMonitorStat stats) { // Use OpenHardwareMonitor to add any missing data if needed stats = SupplementMinerMonitorStatData(accountId, workerName, stats); // Send data to API MinerMonitorStatsAPI minerMonitorStatsAPI = new MinerMonitorStatsAPI(); minerMonitorStatsAPI.PostMinerMonitorStats(stats); }
/// <summary> /// Helper method to post miner stats back to the website /// </summary> /// <param name="stats"></param> protected void PostMinerMonitorStat(MinerMonitorStat stats) { // Use OpenHardwareMonitor to add any missing data if needed stats = SupplementMinerMonitorStatData(stats); // Send data to API MinerMonitorStatsAPI minerMonitorStatsAPI = new MinerMonitorStatsAPI(); minerMonitorStatsAPI.PostMinerMonitorStats(stats); }
/// <summary> /// Map Claymore response to BPM statistics objects /// </summary> /// <param name="claymoreTemplate"></param> /// <returns></returns> private MinerMonitorStat MapRPCResponse(ClaymoreTemplate claymoreTemplate) { try { // Create new Miner monitor stats object MinerMonitorStat minerMonitorStat = new MinerMonitorStat { AccountGuid = (Guid)Application.Current.Properties["AccountID"], WorkerName = Application.Current.Properties["WorkerName"].ToString(), CoinType = this.CoinType, MinerBaseType = MinerBaseType }; if (claymoreTemplate.result.Count > 0) { List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); string[] hashRates = claymoreTemplate.result[3].Split(';'); string[] tempFans = claymoreTemplate.result[6].Split(';'); for (int i = 0; i < hashRates.GetLength(0); i++) { // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat { AccountGuid = (Guid)Application.Current.Properties["AccountID"], WorkerName = Application.Current.Properties["WorkerName"].ToString(), CoinType = this.CoinType.ToString(), GPUID = i, // Returned hashrate is in MH. Format later, return in KH/s same as CCMiner for now HashRate = Convert.ToDecimal(hashRates[i]) * 1024, FanSpeed = 0, // Let OpenHardwareMonitor get the fanspeed Temp = Convert.ToInt16(tempFans[i * 2]), Power = 0, HardwareType = Hardware }; // Sum up power and hashrate minerMonitorStat.Power += gpuMonitorStat.Power; minerMonitorStat.HashRate += gpuMonitorStat.HashRate; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; } return(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error mapping RPC Response for claymore miner"); return(null); } }
/// <summary> /// Map DSTM response to BPM statistics objects /// </summary> /// <param name="dstmTemplate"></param> /// <returns></returns> private MinerMonitorStat MapRPCResponse(Guid accountId, string workerName, DSTMTemplate dstmTemplate) { try { // Create new Miner monitor stats object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat.AccountGuid = accountId; minerMonitorStat.WorkerName = workerName; minerMonitorStat.CoinType = this.CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; if (dstmTemplate.result.Count > 0) { List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); foreach (DSTMOBjectTemplate dstmOBjectTemplate in dstmTemplate.result) { // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat { AccountGuid = accountId, WorkerName = workerName, CoinType = this.CoinType, GPUID = dstmOBjectTemplate.gpu_id, HashRate = dstmOBjectTemplate.sol_ps, FanSpeed = 0, Temp = (short)dstmOBjectTemplate.temperature, Power = (short)dstmOBjectTemplate.power_usage, HardwareType = Hardware }; // Sum up power and hashrate minerMonitorStat.Power += (short)dstmOBjectTemplate.power_usage; minerMonitorStat.HashRate += dstmOBjectTemplate.sol_ps; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; } return(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error mapping RPC Response for DSTM miner"); return(null); } }
/// <summary> /// Map TRex response to BPM statistics objects /// </summary> /// <param name="trexTemplate"></param> /// <returns></returns> private MinerMonitorStat MapRPCResponse(TRexTemplate trexTemplate) { try { // Create new Miner monitor stats object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; minerMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); minerMonitorStat.CoinType = this.CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; if (trexTemplate.gpus.Count > 0) { List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); foreach (GPUList trexGPU in trexTemplate.gpus) { // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat { AccountGuid = (Guid)Application.Current.Properties["AccountID"], WorkerName = Application.Current.Properties["WorkerName"].ToString(), CoinType = this.CoinType.ToString(), GPUID = trexGPU.device_id, HashRate = trexGPU.hashrate, FanSpeed = (short)trexGPU.fan_speed, Temp = (short)trexGPU.temperature, Power = (short)trexGPU.power, HardwareType = Hardware }; // Sum up power and hashrate minerMonitorStat.Power += trexGPU.power; minerMonitorStat.HashRate += trexGPU.hashrate; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; } return(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error mapping RPC Response for TRex miner"); return(null); } }
/// <summary> /// Check miner stats for missing data and add if needed /// </summary> /// <param name="stats"></param> /// <returns></returns> private bool CheckMinerMonitorStatDataMissing(MinerMonitorStat stats) { bool IsDataMissing = false; foreach (GPUMonitorStat gpuMonitorStat in stats.GPUMonitorStatList) { // Check if FanSpeed is showing 0 if (gpuMonitorStat.FanSpeed == 0) { IsDataMissing = true; } } return(IsDataMissing); }
/// <summary> /// Map XMRig response to BPM statistics objects /// </summary> /// <param name="XMRigTemplate"></param> /// <returns></returns> private MinerMonitorStat MapRPCResponse(XMRigTemplate xmrigTemplate) { try { // Create new Miner monitor stats object MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); minerMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; minerMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); minerMonitorStat.CoinType = this.CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; List <GPUMonitorStat> gpuMonitorStatsList = new List <GPUMonitorStat>(); GPUMonitorStat gpuMonitorStat = new GPUMonitorStat(); gpuMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; gpuMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); gpuMonitorStat.CoinType = this.CoinType.ToString(); gpuMonitorStat.GPUID = 0; gpuMonitorStat.HardwareName = xmrigTemplate.cpu.brand; gpuMonitorStat.HashRate = (decimal)xmrigTemplate.hashrate.highest; gpuMonitorStat.FanSpeed = 0; gpuMonitorStat.Temp = 0; gpuMonitorStat.Power = 0; gpuMonitorStat.HardwareType = Hardware; // Sum up power and hashrate minerMonitorStat.Power += 0; minerMonitorStat.HashRate += gpuMonitorStat.HashRate; // Add GPU stats to list gpuMonitorStatsList.Add(gpuMonitorStat); // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatsList; return(minerMonitorStat); } catch (Exception e) { NLogProcessing.LogError(e, "Error mapping RPC Response for XMRig miner"); return(null); } }
/// <summary> /// Get responses from /// </summary> /// <param name="minerMonitorStat"></param> /// <returns></returns> private WhatToMineResponse GetWhatToMineEstimates(MinerMonitorStat minerMonitorStat) { // Build up Query Parameters for API request NameValueCollection nameValueCollection = new NameValueCollection(); // This is invariant, always use USD based formatting for W2M calls NumberFormatInfo format = new NumberFormatInfo(); // Set the 'splitter' for thousands format.NumberGroupSeparator = ","; // Set the decimal seperator format.NumberDecimalSeparator = "."; if (minerMonitorStat.CoinType == CoinType.MONA || minerMonitorStat.CoinType == CoinType.VTC) { nameValueCollection.Add("hr", (minerMonitorStat.HashRate / 1000).ToString(format)); } else if (minerMonitorStat.CoinType == CoinType.EXP || minerMonitorStat.CoinType == CoinType.ETC || minerMonitorStat.CoinType == CoinType.ETH) { // Expects MH/s nameValueCollection.Add("hr", (minerMonitorStat.HashRate / 1000000).ToString(format)); } else { nameValueCollection.Add("hr", minerMonitorStat.HashRate.ToString(format)); } nameValueCollection.Add("p", minerMonitorStat.Power.ToString()); nameValueCollection.Add("fee", "0.05"); // Pool Fee nameValueCollection.Add("cost", "0.1"); // Elec cost per kwh nameValueCollection.Add("hcost", "0.0"); // Hardware costs nameValueCollection.Add("commit", "Calculate"); // Calc nameValueCollection.Add("revenue", "24h"); // 24 hour results // Load WhatToMine forecasts WhatToMineResponse whatToMineResponse = new WhatToMineResponse(); WhatToMineAPI whatToMineAPI = new WhatToMineAPI(); whatToMineResponse = whatToMineAPI.GetWhatToMineEstimates(minerMonitorStat.CoinType, nameValueCollection); return(whatToMineResponse); }
private async Task <MinerMonitorStat> GetRPCResponse(Guid accountId, string workerName) { MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); try { var dictHW = PruvotApi.GetHwInfo(HostName, ApiPort); var dictHist = PruvotApi.GetHistory(HostName, ApiPort); minerMonitorStat.AccountGuid = accountId; minerMonitorStat.WorkerName = workerName; minerMonitorStat.CoinType = CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; var gpuList = (from element in dictHist orderby element["GPU"] ascending select element["GPU"]).Distinct(); List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); foreach (var gpuNumber in gpuList) { var gpuHash = (from element in dictHist orderby element["GPU"] ascending, element["TS"] descending where element["GPU"] == gpuNumber select element).FirstOrDefault(); var gpuHw = (from hw in dictHW where hw["GPU"] == gpuNumber select hw).FirstOrDefault(); // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat(); gpuMonitorStat.AccountGuid = accountId; gpuMonitorStat.WorkerName = workerName; gpuMonitorStat.CoinType = CoinType; gpuMonitorStat.GPUID = Convert.ToInt32(gpuNumber); gpuMonitorStat.HashRate = (Convert.ToDecimal(gpuHash["KHS"])); gpuMonitorStat.FanSpeed = Convert.ToInt16(gpuHw["FAN"]); gpuMonitorStat.Temp = (short)Convert.ToDecimal(gpuHw["TEMP"]); gpuMonitorStat.Power = (short)(Convert.ToDecimal(gpuHw["POWER"]) / 1000); gpuMonitorStat.HardwareType = Hardware; // Sum up power and hashrate minerMonitorStat.Power += (short)gpuMonitorStat.Power; minerMonitorStat.HashRate += gpuMonitorStat.HashRate; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; return(await Task.Run(() => { return minerMonitorStat; })); } catch (Exception ex) { NLogProcessing.LogError(ex, "Error calling GetRPCResponse from miner."); // Return null object; return(null); } }
/// <summary> /// Use OpenHardwareMonitor to add any missing data if needed /// </summary> /// <param name="stats"></param> private MinerMonitorStat SupplementMinerMonitorStatData(Guid accountId, string workerName, MinerMonitorStat stats) { // Check if any data is missing from stats if (CheckMinerMonitorStatDataMissing(stats) == true) { try { // Retrive GPU data from OpenHardwareMonitor ObservableCollection <GPUSettings> gpuSettingsList = HardwareMonitor.ScanHardware(accountId, workerName); // Iterate through each GPUMonitorStat and add missing data foreach (GPUMonitorStat gpuMonitorStat in stats.GPUMonitorStatList) { gpuMonitorStat.FanSpeed = gpuSettingsList.Where(x => x.GPUID == gpuMonitorStat.GPUID).FirstOrDefault().Fanspeed; } } catch (Exception) { // Ignore this for now. } } return(stats); }
private async Task <MinerMonitorStat> GetRPCResponse() { MinerMonitorStat minerMonitorStat = new MinerMonitorStat(); try { var clientSocket = new TcpClient(); if (clientSocket.ConnectAsync(HostName, ApiPort).Wait(5000)) { //string get_menu_request = "{\"id\":1, \"method\":\"getstat\"}\n"; //string get_menu_request = "{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"miner_getstat1\"}\n"; string get_menu_request = "summary"; NetworkStream serverStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(get_menu_request); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); byte[] inStream = new byte[clientSocket.ReceiveBufferSize]; await serverStream.ReadAsync(inStream, 0, (int)clientSocket.ReceiveBufferSize); string returndata = System.Text.Encoding.ASCII.GetString(inStream); string[] jsonData = returndata.Split(','); //ewbfTemplate = JsonConvert.DeserializeObject<EWBFTemplate>(jsonData); // Close socket clientSocket.Close(); clientSocket = null; } else { NLogProcessing.LogInfo($"Could not connect to EWBF miner socket on port {ApiPort}"); // Return null object; return(null); } //var dictHW = PruvotApi.GetHwInfo(HostName, ApiPort); //var dictHist = PruvotApi.GetHistory(HostName, ApiPort); minerMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; minerMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); minerMonitorStat.CoinType = CoinType; minerMonitorStat.MinerBaseType = MinerBaseType; var gpuList = new List <int> [0, 1, 2]; //(from element in dictHist // orderby element["GPU"] ascending // select element["GPU"]).Distinct(); List <GPUMonitorStat> gpuMonitorStatList = new List <GPUMonitorStat>(); foreach (var gpuNumber in gpuList) { //var gpuHash = (from element in dictHist // orderby element["GPU"] ascending, element["TS"] descending // where element["GPU"] == gpuNumber // select element).FirstOrDefault(); //var gpuHw = (from hw in dictHW // where hw["GPU"] == gpuNumber // select hw).FirstOrDefault(); // Create new GPU monitor stats object and map values GPUMonitorStat gpuMonitorStat = new GPUMonitorStat(); gpuMonitorStat.AccountGuid = (Guid)Application.Current.Properties["AccountID"]; gpuMonitorStat.WorkerName = Application.Current.Properties["WorkerName"].ToString(); gpuMonitorStat.CoinType = CoinType.ToString(); gpuMonitorStat.GPUID = Convert.ToInt32(gpuNumber); //gpuMonitorStat.HashRate = (Convert.ToDecimal(gpuHash["KHS"])); //gpuMonitorStat.FanSpeed = Convert.ToInt16(gpuHw["FAN"]); //gpuMonitorStat.Temp = (short)Convert.ToDecimal(gpuHw["TEMP"]); //gpuMonitorStat.Power = (short)(Convert.ToDecimal(gpuHw["POWER"]) / 1000); gpuMonitorStat.HardwareType = Hardware; // Sum up power and hashrate minerMonitorStat.Power += (short)gpuMonitorStat.Power; minerMonitorStat.HashRate += gpuMonitorStat.HashRate; // Add GPU stats to list gpuMonitorStatList.Add(gpuMonitorStat); } // Set list of GPU monitor stats minerMonitorStat.GPUMonitorStatList = gpuMonitorStatList; return(await Task.Run(() => { return minerMonitorStat; })); } catch (Exception ex) { NLogProcessing.LogError(ex, "Error calling GetRPCResponse from miner."); // Return null object; return(null); } }