1########
2# INFO
3#
4# Type this to add the item:
5#
6# /statusbar window add hddtemp
7#
8# See
9#
10# /help statusbar
11#
12#
13# If you want to use this script install the hddtemp daemon on the host
14# you like to monitor and set it up, You can use multiple hosts aswell.
15#
16# Example:
17# /set hddtemp_hosts host1 host2 host3
18# /set hddtemp_ports 7634 7635 7553
19#
20# If all the daemons run all on the same port you can set a single port,
21# It will be used for all hosts.
22#
23# Example:
24# /set hddtemp_ports 7634
25#
26# There are 2 coloring threshold settings hddtemp_threshold_green
27# and hddtemp_threshold_red. If the temperature is higher than
28# green and lower then red the color will be yellow.
29#
30# Example:
31# /set hddtemp_threshold_green 35
32# /set hddtemp_threshold_red 45
33#
34# (I don't know if the unit retured by the daemon depends on the
35#  locale. I've Celsius values here.)
36#
37#
38# There is a setting for the degree sign.
39# Since there is a difference between 8bit and utf-8
40# you can set it to what you prefer
41#
42########
43# CHANGES:
44# 0.13 - added forking (not blocking irrsi while fetching the temperatures)
45#######
46# TODO: themeing support
47#
48
49use strict;
50use Irssi;
51use Irssi::TextUI;
52use IO::Socket::INET;
53use POSIX;
54
55use vars qw($VERSION %IRSSI);
56$VERSION = "0.15";
57%IRSSI = (
58    authors     => "Valentin Batz",
59    contact     => "vb\@g-23.org",
60    name        => "hddtemp",
61    description => "adds a statusbar item which shows temperatures of harddisks (with multiple hddtemp-hosts support)",
62    license     => "GPLv2",
63    changed     => "2017-03-16",
64    url         => "http://hurzelgnom.bei.t-online.de/irssi/scripts/hddtemp.pl",
65    sbitems     => "hddtemp"
66);
67
68my $forked;
69my $pipe_tag;
70my $outstring = 'hddtemp...';
71
72sub get_data {
73	my $lines;
74	my @hosts = split(/ /, Irssi::settings_get_str("hddtemp_hosts"));
75	my @ports = split(/ /, Irssi::settings_get_str("hddtemp_ports"));
76	print "hi";
77	while(scalar(@hosts) > scalar(@ports)){
78		push @ports, @ports[0];
79	}
80	my $i=0;
81	for ($i;$i<scalar(@hosts);$i++) {
82		my $sock = IO::Socket::INET->new(PeerAddr => @hosts[$i],
83						 PeerPort => @ports[$i],
84						 Proto => 'tcp',
85						 Timeout => 10);
86		#skip dead hosts
87		next unless $sock;
88		while( $_ = $sock->getline()) {
89			$lines .= $_.';';
90		}
91	}
92	return $lines;
93}
94
95sub get_temp {
96	my ($rh, $wh);
97	pipe($rh, $wh);
98	return if $forked;
99	my $pid = fork();
100	if (!defined($pid)) {
101	    Irssi::print("Can't fork() - aborting");
102	    close($rh); close($wh);
103	    return;
104	}
105  	$forked = 1;
106	if ($pid > 0) {
107		#parent
108		close($wh);
109		Irssi::pidwait_add($pid);
110		$pipe_tag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, $rh);
111		return;
112	}
113
114	my $lines;
115	eval {
116		#child
117		$lines = get_data();
118		#write the reply
119		print ($wh $lines);
120		close($wh);
121	};
122	POSIX::_exit(1);
123}
124
125sub pipe_input {
126	my $rh=shift;
127	my $linesx=<$rh>;
128	close($rh);
129	Irssi::input_remove($pipe_tag);
130	$forked = 0;
131	my %temps;
132	my $green = Irssi::settings_get_int("hddtemp_threshold_green");
133	my $red = Irssi::settings_get_int("hddtemp_threshold_red");
134	my $degree = Irssi::settings_get_str("hddtemp_degree_sign");
135	unless ($linesx) {
136		return(0);
137	}
138	my ($hdd, $model, $temp, $unit);
139	my $i=0;
140	foreach my $lines (split(';', $linesx)) {
141		foreach my $line (split(/\|\|/, $lines)) {
142			#remove heading/traling |
143			$line =~ s/^\|//;
144			$line =~ s/\|$//;
145
146			($hdd, $model, $temp, $unit) = split(/\|/,$line,4);
147
148			$hdd =~ s/(.*)\/(.*)$/$2/;
149			#different colors for different termperatures
150			if ($temp <= $green) {
151				$temps{$i.':'.$hdd} = '%g'.$temp.'%n'.$degree.$unit;
152			} elsif ($temp > $green && $temp < $red) {
153				$temps{$i.':'.$hdd} = '%y'.$temp.'%n'.$degree.$unit;
154			} elsif ($temp >= $red) {
155				$temps{$i.':'.$hdd} = '%r'.$temp.'%n'.$degree.$unit;
156			}
157		}
158		$i++;
159	}
160	my $out='';
161	foreach (sort keys %temps) {
162		$out .= "$_: $temps{$_} ";
163	}
164	$out=~s/\s+$//;
165	# temporal use of $out to prevent statusbar drawing errors
166	$outstring=$out;
167	Irssi::statusbar_items_redraw('hddtemp');
168}
169
170sub sb_hddtemp() {
171	my ($item, $get_size_only) = @_;
172	$item->default_handler($get_size_only, "{sb $outstring}", undef, 1);
173}
174
175Irssi::timeout_add(15000, \&get_temp, undef);
176Irssi::statusbar_item_register('hddtemp', undef, 'sb_hddtemp');
177Irssi::settings_add_str("hddtemp", "hddtemp_hosts","localhost");
178Irssi::settings_add_str("hddtemp", "hddtemp_ports","7634");
179Irssi::settings_add_int("hddtemp", "hddtemp_threshold_green", 35);
180Irssi::settings_add_int("hddtemp", "hddtemp_threshold_red", 45);
181Irssi::settings_add_str("hddtemp", "hddtemp_degree_sign","°");
182Irssi::signal_add("setup changed", \&get_temp);
183get_temp();
184