class Avalon::Miner
Constants
- FIELDS
Field formats: name => [width, pattern, type/conversion]
Public Class Methods
convert_last(x)
click to toggle source
Last share converter (Miner-specific)
# File lib/avalon/miner.rb, line 41 def self.convert_last x y = x[/(?<=Last Share Time=)[\d\.]*/] if y.nil? || y == '0' "never" else my_time(Time.now.getgm.to_i-y.to_i, :relative_time) end end
new(monitor, ip, min_mhs, worker_name=nil)
click to toggle source
Calls superclass method
# File lib/avalon/miner.rb, line 56 def initialize monitor, ip, min_mhs, worker_name=nil @ip, @min_mhs, @worker_name = ip, min_mhs*1000 , worker_name @monitor = monitor @config = Avalon::Config.config # TODO: monitor.config? @fails = 0 super() end
print_headers()
click to toggle source
# File lib/avalon/miner.rb, line 51 def self.print_headers puts "\nMiner status as of #{Time.now.getlocal.asctime}:\nmhs: " + FIELDS.map {|name, (width,_,_ )| name.to_s.rjust(width)}.join(' ') end
Public Instance Methods
get_api(call)
click to toggle source
# File lib/avalon/miner.rb, line 64 def get_api call self[:ping] ? `bash -ic "echo -n '#{call}' | nc #{@ip} 4028"` : "" end
last()
click to toggle source
# File lib/avalon/miner.rb, line 97 def last duration(self[:last]) end
poll(verbose=true)
click to toggle source
# File lib/avalon/miner.rb, line 68 def poll verbose=true self[:ping] = ping @ip status = get_api('summary') + get_api('pools') + get_api('devs') + get_api('stats') @poll_time = Time.now # p get_api('summary') data = self.class.extract_data_from(status) if data.empty? @data = {:ping => self[:ping], :rst => self[:rst]} else @data.merge! data if @config[:monitor][:per_hour] [:getwork, :accept, :reject, :stale, :error].each do |key| self[key] = (self[key]/upminutes*60).round(1) if self[key] end end end self[:pool] = pool_hash puts "#{self}" if verbose end
pool_hash()
click to toggle source
# File lib/avalon/miner.rb, line 113 def pool_hash if @monitor.pool && @worker_name && @monitor.pool[:workers] && @monitor.pool[:workers][@worker_name] @monitor.pool[:workers][@worker_name][:hash_rate].round(0) end end
report()
click to toggle source
Check for any exceptional situations in stats, sound alarm if any
# File lib/avalon/miner.rb, line 120 def report if data[:ping].nil? || data[:unit].nil? @fails += 1 if @fails >= @config[:alert_after] alarm "Miner #{num} did not respond to status query", :failure end else @fails = 0 @last_restart ||= restart_time # Detect Miner reset correctly if (restart_time - @last_restart) > 20 @last_restart = restart_time self[:rst] = (self[:rst] || 0) + 1 alarm "Miner #{num} restarted", :restart elsif unit_hash == 0 && last == 'never' && temp == 0 alarm "Miner #{num} is stuck in error state!!!", :failure elsif upminutes > 5 # Miner settled down if unit_hash < @min_mhs alarm "Miner #{num} performance is #{unit_hash}, should be #{@min_mhs}", :perf_low elsif last == 'never' || last > @config[:alert_last_share] alarm "Miner #{num} last shares was #{last} min ago", :last_share elsif temp && temp >= @config[:alert_temp_high] alarm "Miner #{num} too hot at #{temp}°C, needs cooling", :temp_high elsif self[:freq] && temp && temp <= @config[:alert_temp_low] alarm "Miner #{num} temp low at #{temp}°C, is it hashing at all?", :temp_low end end end end
reset()
click to toggle source
Reset or reboot Miner
# File lib/avalon/miner.rb, line 152 def reset `ssh root@#{ip} "reboot"` end
restart_time()
click to toggle source
# File lib/avalon/miner.rb, line 101 def restart_time @poll_time - upminutes * 60.0 end
temp()
click to toggle source
# File lib/avalon/miner.rb, line 105 def temp self[:'°C'] end
to_s()
click to toggle source
# File lib/avalon/miner.rb, line 156 def to_s num.to_s.rjust(3) + ": " + FIELDS.map {|key, (width, _, _ )| @data[key].to_s.rjust(width)}.join(" ") end
unit_hash()
click to toggle source
# File lib/avalon/miner.rb, line 109 def unit_hash self[:unit] || 0 end
upminutes()
click to toggle source
# File lib/avalon/miner.rb, line 93 def upminutes duration(self[:uptime]) end