#!/usr/bin/ruby # # Copyright (c) 2006 Peter Palfrader # #%# family=auto #%# capabilities=autoconf suggest # # Munin plugin to moniture temperatures reported by 1-wire devices # # I use owfs to mount the 1-wire bus to /var/lib/owfs # http://owfs.sourceforge.net/ # # Add the following to your /etc/munin/plugin-conf.d/munin-node: # [owfs_temperature_10.D234EE000800] # user root # env.title in rack 3 # env.label rack 3 # $owfs_path = '/var/lib/owfs' $owfs_path = ENV['OWFSPATH'] if ENV['OWFSPATH'] def bail_out(m) STDERR.puts "#{$0}: #{m}" exit 1 end def autoconf if File.directory?($owfs_path) if File.directory?($owfs_path + '/structure') puts "yes" else puts "no (#{$owfs_path}/structure does not exist or permission denied - owfs not mounted?)" end else puts "no (#{$owfs_path} does not exist or permission denied)" end end def suggest Dir.glob($owfs_path+'/[0-9A-F][0-9A-F].*/temperature').each do |path| puts File.basename(File.dirname(path)) end end def normalize_sensor(s) s = s.downcase s = s.tr('-', 'M') s = s.tr('+', 'P') s.tr('^a-zA-Z0-9', '_') end def query_device match = /_([0-9A-F][0-9A-F]\..*?)$/.match($0) unless match bail_out "Could not figure out which device you want based on executeable name." end match[1] end def config device = query_device title = ENV['title'] ? ENV['title'] : 'Temperatures #{device}' label = ENV['label'] ? ENV['label'] : device puts "graph_title #{title}" puts "graph_args --base 1000" puts "graph_vlabel degrees Celsius"; puts "graph_category sensors" puts "graph_info Temperature reported by 1-wire devices" n = normalize_sensor device puts "#{n}.label #{label}" end def runcmd(command, input) rdin , wrin = IO.pipe rdout, wrout = IO.pipe rderr, wrerr = IO.pipe pid = fork unless pid # child wrin.close rdout.close rderr.close STDIN.reopen rdin STDOUT.reopen wrout STDERR.reopen wrerr exec(*command) throw("fell through exec(). WTF.") end rdin.close wrout.close wrerr.close out = [] err = [] tin = Thread.new { wrin.print input; wrin.close } tout = Thread.new { out = rdout.readlines } terr = Thread.new { err = rderr.readlines } tin.join tout.join terr.join Process.wait pid exitstatus = $?.exitstatus [exitstatus, out, err] end def report device = query_device Process.gid=0 Process.egid=0 # fuse does weird checks. this fails: # File.new($owfs_path+'/'+device+'/temperature', "r") ---> FAILS: in `initialize': Permission denied - /var/lib/owfs/10.D234EE000800/temperature (Errno::EACCES) # Sometimes the directory in OWFS does not exist, and cat will say # cat: /var/lib/owfs/10.D234EE000800/temperature: Invalid argument # so retry it a few times, since ls'ing the directory helps on the command line at least 5.times do exitstatus, out, err = runcmd(['cat', $owfs_path+'/'+device+'/temperature'], '') if exitstatus != 0 STDERR.puts "Child exited with non-zero exit code(%d): %s"%[exitstatus >> 8, err.join] runcmd(['ls', $owfs_path]) sleep 1 else STDERR.puts "command succeeded but returned something on stderr: #{err.join}" if err.size > 0 n = normalize_sensor device puts "#{n}.value #{out.join}" return end end STDERR.puts "Could not get data." end case ARGV[0] when "autoconf" autoconf when "suggest" suggest when "config" config else report end