Skip to content

Instantly share code, notes, and snippets.

@znz
Created June 16, 2010 23:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save znz/441401 to your computer and use it in GitHub Desktop.
Save znz/441401 to your computer and use it in GitHub Desktop.
munin plugin for usbrh
#!/bin/sh
# munin plugin for usbrh
# see http://znz.s1.xrea.com/t/?date=20100528
case "$1" in
autoconf)
if [ -r /proc/usbrh/0/status ]; then
echo yes
exit 0
else
echo no
exit 1
fi
;;
config)
echo 'graph_title USBRH'
echo 'graph_args -l 0 --base 1000'
echo 'graph_vlabel temperature(C) and humidity(%RH)'
echo 'graph_category sensors'
cd /proc/usbrh
for n in *; do
echo "humidity_$n.label humidity $n"
echo "humidity_$n.draw LINE2"
echo "humidity_$n.info humidity $n"
echo "temperature_$n.label temperature $n"
echo "temperature_$n.draw LINE2"
echo "temperature_$n.info temperature $n"
done
exit 0
;;
esac
for status in /proc/usbrh/*/status; do
n=$(basename $(dirname $status))
# retry when failed to get temperature/humidity
for i in 1 2 3 4 5; do
stat="$(cat $status)"
case "$stat" in
t*)
break
;;
esac
sleep 1
done
echo $stat | sed -e "s/t:\\([.0-9]*\\) h:\\([.0-9]*\\).*/temperature_$n.value \\1\nhumidity_$n.value \\2/"
done
#!/usr/bin/ruby
=begin
= usbrh.rb
== Feature
* run as munin-plugin
* command line utility like USBRH on Linux
* http://www.dd.iij4u.or.jp/~briareos/soft/usbrh.html
== Requirements
* ruby : http://www.ruby-lang.org/
* ruby-usb : https://github.com/akr/ruby-usb
== Use as munin-plugin
* Create /etc/munin/plugin-conf.d/usbrh with following:
[usbrh]
user root
* Put this to /etc/munin/plugins/usbrh
* Restart munin-node
== License
MIT License. Copyright (C) 2011 Kazuhiro NISHIYAMA
=end
require 'usb'
module USBRH
VENDOR = 0x1774
PRODUCT = 0x1001
# parameter
# http://www.sensirion.com/en/pdf/product_information/Data_Sheet_humidity_sensor_SHT1x_SHT7x_E.pdf
# http://www.syscom-inc.co.jp/pdf/sht_datasheet_j.pdf
D1 = -40.00
D2 = 0.01
C1 = -4.0
C2 = 0.0405
C3 = -0.0000028
T1 = 0.01
T2 = 0.00008
module_function
#Temperature = d1+d2*SOt
# d1 -40.00
# d2 0.04
def convert_temp(input)
D1+D2*input;
end
def convert_humidity(input)
tmp = C1+C2*input+C3*(input*input)
(T1-25)*(T1+T2*input)+tmp
end
def dump(input)
input.bytes.each_with_index do |b,i|
case
when i%16 == 15
printf("%02x\n",b)
when i%8 == 7
printf("%02x-", b)
else
printf("%02x ", b)
end
end
puts
end
def search_devices(vendor=VENDOR, product=PRODUCT)
USB.devices.select do |dev|
dev.idVendor == vendor && dev.idProduct == product
end
end
def list_devices(vendor=VENDOR, product=PRODUCT)
count = 0
puts("listing:USBRH")
USB.devices.each do |dev|
if dev.idVendor == vendor && dev.idProduct == product
count += 1
printf "%d: bus=%s device=%s\n", count, dev.bus.dirname, dev.filename
end
end
printf "%d device(s) found.\n", count
end
def usb_detach_kernel_driver_np(dh, iface_num, e)
if dh.respond_to?(:usb_detach_kernel_driver_np)
if dh.method(:usb_detach_kernel_driver_np).arity == 2
# avoid libusb-ruby's bug
dh.usb_detach_kernel_driver_np(iface_num, nil)
else
dh.usb_detach_kernel_driver_np(iface_num)
end
else
raise e
end
end
def usb_set_configuration(dh, config, iface_num)
dh.set_configuration(config.bConfigurationValue)
rescue SystemCallError => e
usb_detach_kernel_driver_np(dh, iface_num, e)
end
def usb_claim_interface(dh, iface_num)
dh.claim_interface(iface_num)
rescue SystemCallError => e
usb_detach_kernel_driver_np(dh, iface_num, "usb_detach_kernel_driver_np")
dh.claim_interface(iface_num)
end
REQUEST_TYPE = USB::USB_ENDPOINT_OUT + USB::USB_TYPE_CLASS + USB::USB_RECIP_INTERFACE
def usb_control_msg(dh)
buff = "\0" * 7
rc = dh.usb_control_msg(REQUEST_TYPE, USB::USB_REQ_SET_CONFIGURATION, 0x0200, 0, buff, 5000)
if $DEBUG
printf "usb_control_msg OK:send bytes:[%d]\n", rc
dump buff
end
end
def usb_bulk_read(dh)
buff = "\0" * 7
rc = dh.usb_bulk_read(1, buff, 5000)
if $DEBUG
printf "usb_bulk_read:[%d] bytes read.\n", rc
dump buff
end
buff
end
def read_pair(dh)
buff = usb_bulk_read(dh)
iTemperature = buff[2] << 8 | (buff[3] & 0xff)
iHumidity = buff[0] << 8 | (buff[1] & 0xff)
if $DEBUG
printf "convert to integer(temperature):[%02x %02x] -> [%04x]\n", buff[2], buff[3], iTemperature
printf "convert to integer(humidity):[%02x %02x] -> [%04x]\n", buff[0], buff[1], iHumidity
end
temperature = convert_temp(iTemperature)
humidity = convert_humidity(iHumidity)
return [temperature, humidity]
end
def get(dev, sleep_sec=1)
# usb_open
dev.open do |dh|
config, = dev.configurations
interface, = config.interfaces
setting, = interface.settings
iface_num = setting.bInterfaceNumber
usb_set_configuration(dh, config, iface_num)
usb_claim_interface(dh, iface_num)
usb_control_msg(dh)
sleep(sleep_sec)
pair = read_pair(dh)
dh.usb_release_interface(iface_num)
return pair
end
end
end
if __FILE__ == $0
require 'optparse'
debug = false
devnum = nil
sleep_sec = 1
format = "default"
format_proc = {
"verbose" => proc {|n, t, h|
printf "Temperature: %.2f C\n", t
printf "Humidity: %.2f %\n", h
},
"mrtg-temperature" => proc {|n, t, h|
printf "%.2f\n%.2f\n\nTemperature\n", t, t
},
"mrtg-humidity" => proc {|n, t, h|
printf "%.2f\n%.2f\n\nHumidity\n", h, h
},
"mrtg" => proc {|n, t, h|
printf "%.2f\n%.2f\n\nTemperature/Humidity\n", t, h
},
"oneline" => proc {|n, t, h|
printf "Temperature: %.2f C Humidity: %.2f %%\n", t, h
},
"simple" => proc {|n, t, h|
printf "%.2f %.2f\n", t, h
},
"default" => proc {|n, t, h|
printf "temperature_%d.value %.2f\n", n, t
printf "humidity_%d.value %.2f\n", n, h
},
}
ARGV.options do |opts|
opts.on("-fn", "--device=n", "set device number(n>0)", Integer) do |n|
devnum = n
end
opts.on("-o", "--format=FORMAT", format_proc.keys,
"output format", "("+format_proc.keys.sort.join(", ")+")") do |f|
format = f
end
opts.on("-s", "--sleep=SEC", "sleep seconds before read", Float) do |s|
sleep_sec = s
end
opts.on("-l", "--list", "List devices") do
USBRH.list_devices
exit
end
opts.parse!
end
devices = USBRH.search_devices
if devnum
devices = [USBRH.search_devices[devnum-1]].compact
end
case ARGV[0]
when "autoconf"
if devices.empty?
puts "no"
else
puts "yes"
end
exit
when "config"
puts 'graph_title USBRH'
puts 'graph_args -l 0 --base 1000'
puts 'graph_vlabel temperature(C) and humidity(%RH)'
puts 'graph_category sensors'
devices.each_with_index do |dev, n|
puts "humidity_#{n}.label humidity #{n}"
puts "humidity_#{n}.draw LINE2"
puts "humidity_#{n}.info humidity #{n}"
puts "temperature_#{n}.label temperature #{n}"
puts "temperature_#{n}.draw LINE2"
puts "temperature_#{n}.info temperature #{n}"
end
exit
end
if devices.empty?
exit
end
devices.each_with_index do |dev, n|
temperature, humidity = USBRH.get(dev, sleep_sec)
format_proc[format].call(n, temperature, humidity)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment