Class: Avalon::Miner
- Extended by:
- Extractable
- Defined in:
- lib/avalon/miner.rb
Overview
Miner is a node encapsulating a single Avalon unit
Constant Summary collapse
- FIELDS =
Field formats: name => [width, pattern, type/conversion]
{ :unit => [6, /(?<=MHS av=)[\d\.]*/, :i], :pool => [6, /./, nil], # not in miner status string... :ping => [6, /./, nil], # not in miner status string... :rst => [3, /./, nil], # not in miner status string... :uptime => [9, /(?<=Elapsed=)[\d\.]*/, ->(x){ my_time(x, :relative_time)}], :last => [8, /(?<=Status=Alive,).*?Last Share Time=[\d\.]*/, ->(x){ convert_last(x)}], :miner => [5, /(?<=Description=cgminer )[\d\.]*/, :s], :freq => [4, /(?<=frequency=)[\d\.]*/, :i], :'°C' => [2, /(?<=Temperature=)[\d\.]*/, :i], :fan2 => [4, /(?<=fan2=)[\d\.]*/, :i], :fan3 => [4, /(?<=fan3=)[\d\.]*/, :i], :WU => [4, /(?<=,Work Utility=)[\d\.]*/, :i], :getwork => [7, /(?<=Getworks=)[\d\.]*/, :i], :accept => [6, /(?<=,Accepted=)[\d\.]*/, :i], :reject => [6, /(?<=Rejected=)[\d\.]*/, :i], :stale => [5, /(?<=Stale=)[\d\.]*/, :i], :error => [6, /(?<=Hardware Errors=)[\d\.]*/, :i], # :block => [5, /(?<=Network Blocks=)[\d\.]*/, :i], # :found => [2, /(?<=Found Blocks=)[\d\.]*/, :i], }
Instance Attribute Summary
Attributes inherited from Node
Class Method Summary collapse
-
.convert_last(x) ⇒ Object
Last share converter (Miner-specific).
- .print_headers ⇒ Object
Instance Method Summary collapse
- #get_api(call) ⇒ Object
-
#initialize(monitor, ip, min_mhs, worker_name = nil) ⇒ Miner
constructor
A new instance of Miner.
- #last ⇒ Object
- #poll(verbose = true) ⇒ Object
- #pool_hash ⇒ Object
-
#report ⇒ Object
Check for any exceptional situations in stats, sound alarm if any.
-
#reset ⇒ Object
Reset or reboot Miner.
- #restart_time ⇒ Object
- #temp ⇒ Object
- #to_s ⇒ Object
- #unit_hash ⇒ Object
- #upminutes ⇒ Object
Methods included from Extractable
extract_data_from, my_time, print_headers
Methods inherited from Node
Methods included from Utils
#alarm, #duration, #find_file, #ping, #play, #system
Constructor Details
#initialize(monitor, ip, min_mhs, worker_name = nil) ⇒ Miner
Returns a new instance of Miner.
56 57 58 59 60 61 62 |
# 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 |
Class Method Details
.convert_last(x) ⇒ Object
Last share converter (Miner-specific)
41 42 43 44 45 46 47 48 49 |
# 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 |
.print_headers ⇒ Object
51 52 53 54 |
# 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 |
Instance Method Details
#get_api(call) ⇒ Object
64 65 66 |
# File 'lib/avalon/miner.rb', line 64 def get_api call self[:ping] ? `bash -ic "echo -n '#{call}' | nc #{@ip} 4028"` : "" end |
#last ⇒ Object
97 98 99 |
# File 'lib/avalon/miner.rb', line 97 def last duration(self[:last]) end |
#poll(verbose = true) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# 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 ⇒ Object
113 114 115 116 117 |
# 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 ⇒ Object
Check for any exceptional situations in stats, sound alarm if any
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# 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 ⇒ Object
Reset or reboot Miner
152 153 154 |
# File 'lib/avalon/miner.rb', line 152 def reset `ssh root@#{ip} "reboot"` end |
#restart_time ⇒ Object
101 102 103 |
# File 'lib/avalon/miner.rb', line 101 def restart_time @poll_time - upminutes * 60.0 end |
#temp ⇒ Object
105 106 107 |
# File 'lib/avalon/miner.rb', line 105 def temp self[:'°C'] end |
#to_s ⇒ Object
156 157 158 159 |
# 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 ⇒ Object
109 110 111 |
# File 'lib/avalon/miner.rb', line 109 def unit_hash self[:unit] || 0 end |
#upminutes ⇒ Object
93 94 95 |
# File 'lib/avalon/miner.rb', line 93 def upminutes duration(self[:uptime]) end |