————————————package
Power::Outlet::Shelly;
use
strict;
use
warnings;
our
$VERSION
=
'0.50'
;
=head1 NAME
Power::Outlet::Shelly - Control and query a Shelly GIPO Relay with HTTP REST API
=head1 SYNOPSIS
my $outlet = Power::Outlet::Shelly->new(host=>"shelly", index=>0);
print $outlet->query, "\n";
print $outlet->on, "\n";
print $outlet->off, "\n";
print $outlet->switch, "\n";
print $outlet->cycle, "\n";
=head1 DESCRIPTION
Power::Outlet::Shelly is a package for controlling and querying a relay index on Shelly hardware.
Commands can be executed via web (HTTP) requests, for example:
http://<ip>/relay/0?turn=on
http://<ip>/relay/0?turn=off
http://<ip>/relay/0?turn=toggle
http://<ip>/relay/0?timer=5
=head1 USAGE
use Power::Outlet::Shelly;
my $outlet = Power::Outlet::Shelly->new(host=>"sw-kitchen", style=>"relay", index=>0);
print $outlet->on, "\n";
Command Line
$ power-outlet Shelly ON host sw-kitchen style relay index 0
Command Line (from settings)
$ cat /etc/power-outlet.ini
[Kitchen]
type=Shelly
name=Kitchen
host=sw-kitchen
style=relay
index=0
groups=Inside Lights
groups=Main Floor
$ power-outlet Config ON section Kitchen
=head1 CONSTRUCTOR
=head2 new
my $outlet = Power::Outlet->new(type=>"Shelly", host=>"shelly", index=>0);
my $outlet = Power::Outlet::Shelly->new(host=>"shelly", index=>0);
=head1 PROPERTIES
=head2 style
Set the style to support "relay" (1, 1L, 2.5, 4, Plug, Uni, EM, 3EM), "light" (Dimmer, Bulb, Vintage, Duo), "color" (RGB Color), or "white" (RGB White)
my $style = $outlet->style;
my $style = $outlet->style('light');
default: relay
=cut
sub
style {
my
$self
=
shift
;
$self
->{
'style'
} =
shift
if
@_
;
$self
->{
'style'
} =
$self
->_style_default
unless
defined
$self
->{
'style'
};
return
$self
->{
'style'
};
}
sub
_style_default {
'relay'
};
=head2 index
Shelly hardware supports zero or more relay indexes starting at 0.
Default: 0
=cut
sub
index
{
my
$self
=
shift
;
$self
->{
'index'
} =
shift
if
@_
;
$self
->{
'index'
} =
$self
->_index_default
unless
defined
$self
->{
'index'
};
return
$self
->{
'index'
};
}
sub
_index_default {0};
=head2 host
Sets and returns the hostname or IP address.
Default: shelly
=cut
sub
_host_default {
'shelly'
};
=head2 port
Sets and returns the port number.
Default: 80
=cut
sub
_port_default {
'80'
};
#override Power::Outlet::Common::IP->_port_default
=head1 METHODS
=head2 name
=cut
#GET /settings/relay/{index} -> $return->{'name'}
sub
_name_default {
my
$self
=
shift
;
return
$self
->_call(
'/settings'
)->{
'name'
};
}
=head2 query
Sends an HTTP message to the device to query the current state
=cut
sub
query {
my
$self
=
shift
;
return
$self
->_call(
''
)->{
'ison'
} ?
'ON'
:
'OFF'
;
}
=head2 on
Sends a message to the device to Turn Power ON
=cut
sub
on {
my
$self
=
shift
;
return
$self
->_call(
''
,
turn
=>
'on'
)->{
'ison'
} ?
'ON'
:
'OFF'
;
}
=head2 off
Sends a message to the device to Turn Power OFF
=cut
sub
off {
my
$self
=
shift
;
return
$self
->_call(
''
,
turn
=>
'off'
)->{
'ison'
} ?
'ON'
:
'OFF'
;
}
=head2 switch
Sends a message to the device to toggle the power
=cut
#override Power::Outlet::Common->switch
sub
switch {
my
$self
=
shift
;
return
$self
->_call(
''
,
turn
=>
'toggle'
)->{
'ison'
} ?
'ON'
:
'OFF'
;
}
=head2 cycle
Sends messages to the device to Cycle Power (ON-OFF-ON or OFF-ON-OFF).
=cut
#override Power::Outlet::Common->cycle
sub
cycle {
my
$self
=
shift
;
my
$cycle_duration
=
$self
->cycle_duration;
#from Power::Outlet::Common
my
$hash
=
$self
->_call(
''
,
timer
=>
$cycle_duration
);
return
$hash
->{
'timer_started'
} > 0 ?
'CYCLE'
#is this the correct logic?
:
$hash
->{
'ison'
} ?
'ON'
:
'OFF'
;
}
=head2 cycle_duration
Default; 10 seconds (floating point number)
=cut
sub
_call {
my
$self
=
shift
;
my
$settings
=
shift
;
my
%param
=
@_
;
#http://<ip>/settings/relay/0
#http://<ip>/relay/0?turn=on
#http://<ip>/relay/0?timer=10
$self
->http_path(
sprintf
(
'%s/%s/%s'
,
$settings
,
$self
->style,
$self
->
index
));
my
$url
=
$self
->url(
undef
);
#isa URI from Power::Outlet::Common::IP::HTTP
$url
->query_form(
%param
);
my
$hash
=
$self
->json_request(
GET
=>
$url
);
#isa HASH
die
(
'Error: Method _call failed to return expected JSON format'
)
unless
ref
(
$hash
) eq
'HASH'
;
return
$hash
;
}
=head1 BUGS
Please log on RT and send an email to the author.
=head1 SUPPORT
DavisNetworks.com supports all Perl applications including this package.
=head1 AUTHOR
Michael R. Davis
CPAN ID: MRDVT
DavisNetworks.com
=head1 COPYRIGHT
Copyright (c) 2020 Michael R. Davis
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
=head1 SEE ALSO
=cut
1;