Skip to content

Commit

Permalink
Fix CLI help bug, add support for sysfs/drm
Browse files Browse the repository at this point in the history
  • Loading branch information
ryukoposting committed Feb 9, 2024
1 parent 85912b0 commit 4c04247
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 15 deletions.
26 changes: 25 additions & 1 deletion lib/sensething.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
require_relative 'sensething/nvidia'
require_relative 'sensething/cli'
require_relative 'sensething/timestamp'
require 'pathname'

module SenseThing
def self.discover_devices(&block)
discover_hwmon_devices(&block)
discover_cpufreq_devices(&block)
NvidiaSmi::SmiDevice.enumerate_gpus(&block)
discover_drm_devices(&block)
end

def self.discover_hwmon_devices
Dir.glob('/sys/class/hwmon/*').each do |path|
dev = begin
Sysfs::Hwmon.new(path)
Expand All @@ -17,7 +25,9 @@ def self.discover_devices(&block)

yield dev
end
end

def self.discover_cpufreq_devices(&block)
Dir.glob('/sys/devices/system/cpu/*/cpufreq') do |path|
dev = begin
Sysfs::Cpufreq.new(path)
Expand All @@ -28,7 +38,21 @@ def self.discover_devices(&block)

yield dev
end
end

NvidiaSmi::SmiDevice.enumerate_gpus(&block)
def self.discover_drm_devices(&block)
Dir.glob('/sys/class/drm/*').each do |path|
path = Pathname.new(path).realpath
next unless path.join('gt').directory?

dev = begin
Sysfs::Drm.new(path)
rescue StandardError => e
warn "Tried to access a device at #{path.inspect}, but threw an exception: #{e}"
warn e.backtrace
end

yield dev
end
end
end
1 change: 1 addition & 0 deletions lib/sensething/cli.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'optparse'
require 'set'
require 'io/console'

module SenseThing
Expand Down
1 change: 1 addition & 0 deletions lib/sensething/nvidia/smi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def self.enumerate_gpus
end
end
end
rescue Errno::ENOENT # rubocop:disable Lint/SuppressedException
end

def each_sensor # rubocop:disable Metrics/CyclomaticComplexity
Expand Down
26 changes: 13 additions & 13 deletions lib/sensething/sysfs/cpufreq.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ def self.parse_attr_by_name(path)
name = path.basename.to_s
case name
when 'scaling_cur_freq'
FrequencyValue.new(path)
CpuFrequencyValue.new(path)
when 'scaling_min_freq'
FrequencyMin.new(path)
CpuFrequencyMin.new(path)
when 'scaling_max_freq'
FrequencyMax.new(path)
CpuFrequencyMax.new(path)
when 'scaling_governor'
Governor.new(path)
CpuGovernor.new(path)
end
end

Expand Down Expand Up @@ -70,13 +70,13 @@ def initialize(device, attrs)
@device = device
attrs.each do |a|
case a
when FrequencyMin
when CpuFrequencyMin
@min_attr = a
when FrequencyMax
when CpuFrequencyMax
@max_attr = a
when FrequencyValue
when CpuFrequencyValue
@value_attr = a
when Governor
when CpuGovernor
@governor_attr = a
end
end
Expand Down Expand Up @@ -117,26 +117,26 @@ def summary
def detail
result = []
result << "value: #{value_attr.path}" if value_attr
result << "governor: #{governor_attr.path}" if governor_attr
result << "CpuGovernor: #{governor_attr.path}" if governor_attr
result << "min: #{min_attr.path}" if min_attr
result << "max: #{max_attr.path}" if max_attr
result.join("\n")
end
end

class FrequencyValue < CpufreqAttribute
class CpuFrequencyValue < CpufreqAttribute
include Megahertz
end

class FrequencyMin < CpufreqAttribute
class CpuFrequencyMin < CpufreqAttribute
include Megahertz
end

class FrequencyMax < CpufreqAttribute
class CpuFrequencyMax < CpufreqAttribute
include Megahertz
end

class Governor < CpufreqAttribute
class CpuGovernor < CpufreqAttribute
def fetch
@val = read.strip
end
Expand Down
127 changes: 126 additions & 1 deletion lib/sensething/sysfs/drm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,131 @@
require_relative 'attribute'
require_relative 'device'

# TODO
module Sysfs
class DrmAttribute < Attribute
module Megahertz
def fetch
@val = Float(read)
end

def unit
'MHz'
end

def same_sensor?(_other)
true # for drm, each 'device' represents a single sensor
end
end
end

class Drm < Device
def self.parse_attr_by_name(path)
path = Pathname.new(path.to_s) unless path.is_a? Pathname
name = path.basename.to_s
case name
when 'gt_cur_freq_mhz'
DrmFrequencyValue.new(path)
when 'gt_min_freq_mhz'
DrmFrequencyMin.new(path)
when 'gt_max_freq_mhz'
DrmFrequencyMax.new(path)
when 'gt_boost_freq_mhz'
DrmFrequencyBoost.new(path)
end
end

def create_sensor(attrs)
DrmSensor.new(self, attrs)
end

protected

def discover_attributes
attrs = []
@path.each_child do |pn|
if (attr = self.class.parse_attr_by_name(pn))
attrs << attr
end
end
@attrs = attrs
end

def discover_name
@name = path.basename
end
end

class DrmSensor < SenseThing::Sensor
attr_reader :device, :min_attr, :max_attr, :value_attr, :boost_attr

def initialize(device, attrs)
super()
@device = device
attrs.each do |a|
case a
when DrmFrequencyValue
@value_attr = a
when DrmFrequencyMin
@min_attr = a
when DrmFrequencyMax
@max_attr = a
when DrmFrequencyBoost
@boost_attr = a
end
end
end

def fetch
value_attr&.fetch
end

def value(fetch: false)
value_attr&.value(fetch: fetch)
end

def minimum
min_attr&.value
end

def maximum
max_attr&.value
end

def unit
value_attr&.unit
end

def name
"#{device.name}/frequency"
end

def summary
"Graphics Frequency (drm/#{device.path.basename})"
end

def detail
result = []
result << "value: #{value_attr.path}" if value_attr
result << "min: #{min_attr.path}" if min_attr
result << "max: #{max_attr.path}" if max_attr
result << "boost: #{boost_attr.path}" if boost_attr
result.join("\n")
end
end

class DrmFrequencyValue < DrmAttribute
include Megahertz
end

class DrmFrequencyMin < DrmAttribute
include Megahertz
end

class DrmFrequencyMax < DrmAttribute
include Megahertz
end

class DrmFrequencyBoost < DrmAttribute
include Megahertz
end
end

0 comments on commit 4c04247

Please sign in to comment.