Created
June 16, 2010 23:02
-
-
Save znz/441401 to your computer and use it in GitHub Desktop.
munin plugin for usbrh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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