line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Power::Outlet::iBoot; |
2
|
3
|
|
|
3
|
|
212878
|
use strict; |
|
3
|
|
|
|
|
30
|
|
|
3
|
|
|
|
|
94
|
|
3
|
3
|
|
|
3
|
|
16
|
use warnings; |
|
3
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
101
|
|
4
|
3
|
|
|
3
|
|
15
|
use base qw{Power::Outlet::Common::IP}; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
1007
|
|
5
|
3
|
|
|
3
|
|
995
|
use IO::Socket; |
|
3
|
|
|
|
|
43754
|
|
|
3
|
|
|
|
|
20
|
|
6
|
3
|
|
|
3
|
|
1388
|
use Time::HiRes qw{sleep}; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
29
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.47'; |
9
|
|
|
|
|
|
|
our $PACKAGE = __PACKAGE__; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Power::Outlet::iBoot - Control and query a Dataprobe iBoot power outlet |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 SYNOPSIS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $outlet=Power::Outlet::iBoot->new( |
18
|
|
|
|
|
|
|
host => "mylamp", |
19
|
|
|
|
|
|
|
port => 80, #sane default from manufacture spec |
20
|
|
|
|
|
|
|
auth => "PASS", #sane default from manufacture spec |
21
|
|
|
|
|
|
|
); |
22
|
|
|
|
|
|
|
print $outlet->query, "\n"; |
23
|
|
|
|
|
|
|
print $outlet->on, "\n"; |
24
|
|
|
|
|
|
|
print $outlet->off, "\n"; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 DESCRIPTION |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Power::Outlet::iBoot is a package for controlling and querying a Dataprobe iBoot network attached power outlet. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
iBoot Protocol: The iBoot uses the TCP (Transport Communication Protocol) to communicate with the client system. To communicate with iBoot, establish a TCP connection using the Port as assigned in iBoot Setup. Once connected use the Send() function to send the commands to the iBoot and the Recv() function to receive the response. After sending a response iBoot will close the connection. The following outlines the commands and their responses. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Source: http://dataprobe.com/files/power/iboot_tcp.pdf |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 USAGE |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
use Power::Outlet::iBoot; |
37
|
|
|
|
|
|
|
use DateTime; |
38
|
|
|
|
|
|
|
my $lamp=Power::Outlet::iBoot->new(host=>"lamp"); |
39
|
|
|
|
|
|
|
my $hour=DateTime->now->hour; |
40
|
|
|
|
|
|
|
my $night=$hour > 20 ? 1 : $hour < 06 ? 1 : 0; |
41
|
|
|
|
|
|
|
if ($night) { |
42
|
|
|
|
|
|
|
print $lamp->on, "\n"; |
43
|
|
|
|
|
|
|
} else { |
44
|
|
|
|
|
|
|
print $lamp->off, "\n"; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 new |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my $outlet=Power::Outlet->new(type=>"iBoot", "host=>"mylamp"); |
52
|
|
|
|
|
|
|
my $outlet=Power::Outlet::iBoot->new(host=>"mylamp"); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 PROPERTIES |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head2 host |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Sets and returns the hostname or IP address. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Manufacturer Default: 192.168.1.254 |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=cut |
64
|
|
|
|
|
|
|
|
65
|
2
|
|
|
2
|
|
6
|
sub _host_default {"192.168.1.254"}; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head2 port |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Sets and returns the TCP port |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Manufacturer Default: 80 |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=cut |
74
|
|
|
|
|
|
|
|
75
|
2
|
|
|
2
|
|
7
|
sub _port_default {"80"}; |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head2 pass |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
Sets and returns the case sensitive password |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Manufacturer Default: PASS |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub pass { |
86
|
4
|
|
|
4
|
1
|
9
|
my $self=shift; |
87
|
4
|
50
|
|
|
|
14
|
$self->{"pass"}=shift if @_; |
88
|
4
|
100
|
|
|
|
10
|
$self->{"pass"}="PASS" unless defined $self->{"pass"}; #MFG Default |
89
|
4
|
|
|
|
|
15
|
return $self->{"pass"}; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 name |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head1 METHODS |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=head2 query |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Sends a TCP/IP message to the iBoot device to query the current state |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=cut |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub _send { |
105
|
0
|
|
|
0
|
|
|
my $self=shift; |
106
|
0
|
0
|
|
|
|
|
my $cmd=shift or die; |
107
|
0
|
|
|
|
|
|
my $msg=sprintf("\e%s\e%s\r", $self->pass, $cmd); |
108
|
|
|
|
|
|
|
#from docs "After sending a response iBoot will close the connection" |
109
|
0
|
|
|
|
|
|
my $sock=IO::Socket::INET->new(PeerAddr => $self->host, |
110
|
|
|
|
|
|
|
PeerPort => $self->port, |
111
|
|
|
|
|
|
|
Proto => 'tcp'); |
112
|
0
|
0
|
|
|
|
|
die(sprintf(qq{Error: $PACKAGE could not connect to host "%s" on port "%s".\n}, |
113
|
|
|
|
|
|
|
$self->host, $self->port)) unless defined $sock; |
114
|
0
|
|
|
|
|
|
$sock->send($msg); |
115
|
0
|
|
|
|
|
|
sleep 0.1; #the manufacturer example uses a full second |
116
|
0
|
|
|
|
|
|
my $stat=""; |
117
|
0
|
|
|
|
|
|
$sock->recv($stat, 5); |
118
|
0
|
0
|
|
|
|
|
die(sprintf(qq{Error: $PACKAGE TCP/IP receive error with host "%s" on port "%s".\n}, |
119
|
|
|
|
|
|
|
$self->host, $self->port)) unless defined $stat; |
120
|
0
|
0
|
|
|
|
|
die(sprintf(qq{Error: $PACKAGE receive error with host "%s" on port "%s". Verify password.\n}, |
121
|
|
|
|
|
|
|
$self->host, $self->port)) unless $stat; |
122
|
0
|
|
|
|
|
|
$sock->close; |
123
|
0
|
|
|
|
|
|
return $stat; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
0
|
|
|
0
|
1
|
|
sub query {shift->_send("q")}; |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=head2 on |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
Sends a TCP/IP message to the iBoot device to Turn Power ON |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=cut |
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
0
|
1
|
|
sub on {shift->_send("n")}; |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 off |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Sends a TCP/IP message to the iBoot device to Turn Power OFF |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=cut |
141
|
|
|
|
|
|
|
|
142
|
0
|
|
|
0
|
1
|
|
sub off {shift->_send("f")}; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head2 switch |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Queries the device for the current status and then requests the opposite. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=cut |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
#see Power::Outlet::Common->switch |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 cycle |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
Sends a TCP/IP message to the iBoot device to Cycle Power (ON-OFF-ON or OFF-ON-OFF). Cycle time is determined by Setup. |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
Manufacturer Default Cycle Period: 10 seconds |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=cut |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
0
|
1
|
|
sub cycle {shift->_send("c")}; |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head1 BUGS |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Please log on RT and send an email to the author. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head1 SUPPORT |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
DavisNetworks.com supports all Perl applications including this package. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=head1 AUTHOR |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
Michael R. Davis |
173
|
|
|
|
|
|
|
CPAN ID: MRDVT |
174
|
|
|
|
|
|
|
DavisNetworks.com |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=head1 COPYRIGHT |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
The full text of the license can be found in the LICENSE file included with this module. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head1 SEE ALSO |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=cut |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
1; |