Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
ryukoposting committed Feb 2, 2024
0 parents commit 6d7f257
Show file tree
Hide file tree
Showing 26 changed files with 2,143 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Ruby
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
- name: Build and test with Rake
run: |
gem install bundler
bundle install --jobs 4 --retry 3
bundle exec rake
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
*.gem
17 changes: 17 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Style/Documentation:
Enabled: false

Metrics/ClassLength:
Enabled: false

Metrics/AbcSize:
Enabled: false

Metrics/MethodLength:
Max: 25

Metrics/CyclomaticComplexity:
Max: 10

Style/PerlBackrefs:
Enabled: false
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source 'https://rubygems.org'

gem 'minitest', '~> 5.21.2'
gem 'rake', '~> 13.0.0'
gem 'rubocop', '~> 1.60'

gem 'open3'
44 changes: 44 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
json (2.7.1)
language_server-protocol (3.17.0.3)
minitest (5.21.2)
open3 (0.1.2)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
racc (1.7.3)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.9.0)
rexml (3.2.6)
rubocop (1.60.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.13.0)
unicode-display_width (2.5.0)

PLATFORMS
x86_64-linux

DEPENDENCIES
minitest (~> 5.21.2)
open3
rake (~> 13.0.0)
rubocop (~> 1.60)

BUNDLED WITH
2.4.10
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SenseThing: A sensor tool for Linux

`sensething` is a CLI tool that aims to:

- Make as many sensors as possible visible from within a single tool,
- Provide a human-friendly way of querying specific sensors,
- Deliver output in formats that are easy to parse (for humans and computers),
- Be as simple to use as possible.

`sensething` provides access to all the same sensors as `lm-sensors`, but it
also includes sensor data from Nvidia graphics cards, as well as CPU clock
frequencies. It will provide access to even more sensors in the future.
42 changes: 42 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'rubocop/rake_task'

GEM_NAME = 'sensething'
GEM_VERSION = '0.0.1'

def del(pattern)
pattern = File.join(__dir__, pattern)
Dir.glob(pattern).each do |f|
File.delete f
end
end

task default: %i[build test]

RuboCop::RakeTask.new(:lint) do |task|
task.patterns = ['lib/**/*.rb', 'test/**/*.rb']
task.fail_on_error = true
end

task :build do
system "gem build #{GEM_NAME} .gemspec"
end

task install: :build do
system "gem install #{GEM_NAME}-#{GEM_VERSION}.gem"
end

task publish: :build do
system "gem push #{GEM_NAME}-#{GEM_VERSION}.gem"
end

task :test do
Dir.glob('test/*.rb').each do |f|
ruby f
end
end

task :clean do
del '*.gem'
end
126 changes: 126 additions & 0 deletions bin/sensething
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'sensething'
require 'csv'
require 'json'

def gather_sensors
result = {}
SenseThing.discover_devices do |dev|
dev.each_sensor do |sensor|
result[sensor.name] = sensor
end
end
result
end

def gather_relevant_sensors(names)
sensors = gather_sensors
names.map do |name|
s = sensors[name]
raise "No sensor with name '#{name}'" unless s

s
end
end

def putline
puts '=' * 80
end

def list_sensors
SenseThing.discover_devices do |dev|
dev.each_sensor do |sensor|
puts "#{sensor.name.to_s.ljust(29)} #{sensor.summary}"
end
end
end

def sensor_info(names)
names ||= []
sensors = gather_relevant_sensors(names)

sensors.each_with_index do |sensor, i|
puts "#{sensor.name.to_s.ljust(29)} #{sensor.summary}"
puts sensor.detail
putline if i < sensors.length - 1
end
end

def read_sensors(names)
names ||= []
sensors = gather_relevant_sensors(names)

sensors.each do |sensor|
# p sensor
puts "#{sensor.name.to_s.ljust(29)} #{sensor.fetch} #{sensor.unit}"
end
end

def log_csv(sensors, interval, units)
$stdout.sync = true
CSV($stdout.dup) do |csv|
csv << sensors.map do |s|
if units
"#{s.name} [#{s.unit}]"
else
s.name.to_s
end
end
loop do
csv << sensors.map(&:fetch)
sleep interval
end
end
end

def log_json(sensors, interval, units)
$stdout.sync = true
loop do
data = sensors.map do |s|
value = s.fetch
if units
[s.name.to_s, { value: value, unit: s.unit }]
else
[s.name.to_s, value]
end
end
data = data.to_h
JSON.dump(data, $stdout)
$stdout.write "\n"
sleep interval
end
end

def log_sensors(names, format, interval, units)
names ||= []
format ||= 'csv'
interval ||= 1
sensors = gather_relevant_sensors(names)

case format
when 'csv'
log_csv(sensors, interval, units)
when 'json'
log_json(sensors, interval, units)
else
raise "Invalid format: #{format}"
end
end

args = SenseThing::Cli.parse_command_line

case args&.cmd&.name
when nil
SenseThing::Cli.show_help
exit 0
when 'list-sensors'
list_sensors
when 'info'
sensor_info(args.cmd[:name])
when 'read'
read_sensors(args.cmd[:name])
when 'log'
log_sensors(args.cmd[:name], args.cmd[:format], args.cmd[:interval], args.cmd[:units])
end
33 changes: 33 additions & 0 deletions lib/sensething.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require_relative 'sensething/sysfs'
require_relative 'sensething/nvidia'
require_relative 'sensething/cli'

module SenseThing
def self.discover_devices(&block)
Dir.glob('/sys/class/hwmon/*').each do |path|
dev = begin
Sysfs::Hwmon.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

Dir.glob('/sys/devices/system/cpu/*/cpufreq') do |path|
dev = begin
Sysfs::Cpufreq.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

NvidiaSmi::SmiDevice.enumerate_gpus(&block)
end
end
Loading

0 comments on commit 6d7f257

Please sign in to comment.