Device-Yeelight/lib/Device/Yeelight/Light.pm
package Device::Yeelight::Light;
use 5.026;
use utf8;
use strict;
use warnings;
use Carp;
use JSON;
use IO::Socket;
=encoding utf8
=head1 NAME
Device::Yeelight::Light - WiFi Smart LED Light
=head1 SYNOPSIS
This module provides base class for Yeelight smart device
=head1 SUBROUTINES/METHODS
=head2 new
Creates new Yeelight light device.
=cut
sub new {
my $class = shift;
my $data = {
id => undef,
location => 'yeelight://',
support => [],
@_,
_socket => undef,
_next_command_id => 1,
};
return bless( $data, $class );
}
sub DESTROY {
my $self = shift;
$self->{_socket}->close if defined $self->{_socket};
}
=head2 is_supported
Checks if method is supported by the device.
=cut
sub is_supported {
my $self = shift;
my ($method) = @_;
unless ( grep { $method =~ m/::$_$/ } @{ $self->{support} } ) {
carp "$method is not supported by this device";
}
return 1;
}
sub AUTOLOAD {
my $self = shift;
our $AUTOLOAD;
return unless $self->is_supported($AUTOLOAD);
$self->call( $AUTOLOAD, @_ );
return $self;
}
sub command_id {
my $self = shift;
$self->{_next_command_id}++;
}
=head2 connection
Create and return socket connected to the device.
=cut
sub connection {
my $self = shift;
return $self->{_socket}
if defined $self->{_socket} and $self->{_socket}->connected;
my ( $addr, $port ) = $self->{location} =~ m#yeelight://([^:]*):(\d*)#;
$self->{_socket} = IO::Socket::INET->new(
PeerAddr => $addr,
PeerPort => $port,
ReuseAddr => 1,
Proto => 'tcp',
) or croak $!;
return $self->{_socket};
}
=head2 call
Sends command to device.
=cut
sub call {
my $self = shift;
my ( $cmd, @params ) = @_;
my $id = $self->command_id;
my $package = __PACKAGE__;
my $json = encode_json(
{
id => $id,
method => $cmd =~ s/^${package}:://r,
params => \@params,
}
);
$self->connection->send("$json\r\n") or croak $!;
my $buffer;
while ( not $self->connection->recv( $buffer, 4096 ) ) {
my $response = decode_json($buffer);
# Ignore notification messages
next if not defined $response->{id};
carp "Received response to unkown command $response->{id}"
if $response->{id} != $id;
if ( defined $response->{error} ) {
carp
"$response->{error}->{message} (code $response->{error}->{code})";
return;
}
return @{ $response->{result} };
}
}
=head1 Yeelight API CALLS
=cut
use subs
qw/get_prop set_ct_abx set_rgb set_hsv set_bright set_power toggle set_default start_cf stop_cf set_scene cron_add cron_get cron_del set_adjust set_music set_name bg_set_rgb bg_set_hsv bg_set_ct_abx bg_start_cf bg_stop_cf bg_set_scene bg_set_default bg_set_power bg_set_bright bg_set_adjust bg_toggle dev_toggle adjust_bright adjust_ct adjust_color bg_adjust_bright bg_adjust_ct/;
=head2 get_prop
This method is used to retrieve current property of smart LED.
=cut
sub get_prop {
my $self = shift;
my (@properties) = @_;
return unless $self->is_supported( ( caller(0) )[3] );
my @res = $self->call( 'get_prop', @_ );
my $props;
for my $i ( 0 .. $#properties ) {
$props->{ $properties[$i] } = $res[$i];
}
return $props;
}
=head2 set_ct_abx
This method is used to change the color temperature of a smart LED.
=head4 Parameters
=over
=item ct_value
Target color temperature. The type is integer and range is 1700 ~ 6500 (k).
=item effect
Support two values: I<sudden> and I<smooth>. If effect is I<sudden>, then the
color temperature will be changed directly to target value, under this case,
the third parameter I<duration> is ignored. If effect is I<smooth>, then the
color temperature will be changed to target value in a gradual fashion, under
this case, the total time of gradual change is specified in third parameter
I<duration>.
=item duration
Specifies the total time of the gradual changing. The unit is milliseconds. The
minimum support duration is 30 milliseconds.
=back
=head2 set_rgb
This method is used to change the color of a smart LED.
=head4 Parameters
=over
=item rgb_value
Target color, whose type is integer. It should be expressed in decimal integer
ranges from 0 to 16777215 (hex: 0xFFFFFF).
=item effect
Refer to C<set_ct_abx> method.
=item duration
Refer to C<set_ct_abx> method.
=back
=head2 set_hsv
This method is used to change the color of a smart LED.
=head4 Parameters
=over
=item hue
Target hue value, whose type is integer. It should be expressed in decimal
integer ranges from 0 to 359.
=item sat
Target saturation value whose type is integer. It's range is 0 to 100.
=item effect
Refer to C<set_ct_abx> method.
=item duration
Refer to C<set_ct_abx> method.
=back
=head2 set_bright
This method is used to change the brightness of a smart LED.
=head4 Parameters
=over
=item brightness
Target brightness. The type is integer and ranges from 1 to 100. The brightness
is a percentage instead of a absolute value. 100 means maximum brightness while
1 means the minimum brightness.
=item effect
Refer to C<set_ct_abx> method.
=item duration
Refer to C<set_ct_abx> method.
=back
=head2 set_power
This method is used to switch on or off the smart LED (software
managed on/off).
=head4 Parameters
=over
=item power
Can only be I<on> or I<off>. I<on> means turn on the smart LED, I<off> means turn
off the smart LED.
=item effect
Refer to C<set_ct_abx> method.
=item duration
Refer to C<set_ct_abx> method.
=item mode
(optional parameter)
=over
=item 0
Normal turn on operation (default value)
=item 1
Turn on and switch to CT mode.
=item 2
Turn on and switch to RGB mode.
=item 3
Turn on and switch to HSV mode.
=item 4
Turn on and switch to color flow mode.
=item 5
Turn on and switch to Night light mode. (Ceiling light only).
=back
=back
=head2 toggle
This method is used to toggle the smart LED.
=head2 set_default
This method is used to save current state of smart LED in persistent memory. So
if user powers off and then powers on the smart LED again (hard power reset),
the smart LED will show last saved state.
=head2 start_cf
This method is used to start a color flow. Color flow is a series of smart LED
visible state changing. It can be brightness changing, color changing or color
temperature changing. This is the most powerful command.
=head4 Parameters
=over
=item count
Total number of visible state changing before color flow stopped. 0 means
infinite loop on the state changing.
=item action
The action taken after the flow is stopped.
=over
=item 0
means smart LED recover to the state before the color flow started.
=item 1
means smart LED stay at the state when the flow is stopped.
=item 2
means turn off the smart LED after the flow is stopped.
=back
=item flow_expression
The expression of the state changing series.
=over
=item Duration
Gradual change time or sleep time, in milliseconds, minimum value 50.
=item Mode
=over
=item 1
color
=item 2
color temperature
=item 7
sleep
=back
=item Value
=over
=item
RGB value when mode is 1,
=item
CT value when mode is 2,
=item
Ignored when mode is 7
=back
=item Brightness
Brightness value, -1 or 1 ~ 100. Ignored when mode is 7. When this value is
-1, brightness in this tuple is ignored (only color or CT change takes effec
=back
=back
=head2 stop_cf
This method is used to stop a running color flow.
=head2 set_scene
This method is used to set the smart LED directly to specified state. If the
smart LED is off, then it will turn on the smart LED firstly and then apply the
specified command.
=head4 Parameters
=over
=item class
=over
=item I<color>
means change the smart LED to specified color and brightness
=item I<hsv>
means change the smart LED to specified color and brightness
=item I<ct>
means change the smart LED to specified ct and brightness
=item I<cf>
means start a color flow in specified fashion
=item I<auto_delay_off>
means turn on the smart LED to specified brightness and start a sleep timer to
turn off the light after the specified minutes
=back
=item val1
=item val2
=item val3
=back
=head2 cron_add
This method is used to start a timer job on the smart LED.
=head4 Parameters
=over
=item type
Currently can only be 0 (means power off).
=item value
Length of the timer (in minutes).
=back
=head2 cron_get
This method is used to retrieve the setting of the current cron job of the
specified type.
=head4 Parameters
=over
=item type
The type of the cron job (currently only support 0).
=back
=head2 cron_del
This method is used to stop the specified cron job.
=head4 Parameters
=over
=item type
The type of the cron job (currently only support 0).
=back
=head2 set_adjust
This method is used to change brightness, CT or color of a smart LED without
knowing the current value, it's main used by controllers.
=head4 Parameters
=over
=item action
The direction of the adjustment, the valid value can be:
=over
=item I<increase>
increase the specified property
=item I<decrease>
decrease the specified property
=item I<circle>
increase the specified property, after it reaches the max value, go back to
minimum value
=back
=item prop
The property to adjust. The valid value can be:
=over
=item I<bright>
adjust brightness
=item I<ct>
adjust color temperature
=item I<color>
adjust color.
(When C<prop> is I<color>, the C<action> can only be I<circle>, otherwise, it
will be deemed as invalid request.)
=back
=back
=head2 set_music
This method is used to start or stop music mode on a device. Under music mode,
no property will be reported and no message quota is checked.
=head4 Parameters
=over
=item action
The action of C<set_music> command. The valid value can be:
=over
=item 0
turn off music mode
=item 1
turn on music mode
=back
=item host
The IP address of the music server.
=item port
The TCP port music application is listening on.
=back
=head2 set_name
This method is used to name the device. The name will be stored on the device
and reported in discovering response. User can also read the name through
C<get_prop> method.
=head4 Parameters
=over
=item name
The name of the device.
=back
=head2 adjust_bright
This method is used to adjust the brightness by specified percentage within
specified duration.
=head4 Parameters
=over
=item percentage
The percentage to be adjusted. The range is: -100 ~ 100
=item duration
Refer to "set_ct_abx" method.
=back
=head2 adjust_ct
This method is used to adjust the color temperature by specified percentage
within specified duration.
=head4 Parameters
=over
=item percentage
The percentage to be adjusted. The range is: -100 ~ 100
=item duration
Refer to "set_ct_abx" method.
=back
=head2 adjust_color
This method is used to adjust the color within specified duration.
=head4 Parameters
=over
=item percentage
The percentage to be adjusted. The range is: -100 ~ 100
=item duration
Refer to "set_ct_abx" method.
=back
=head2 bg_set_xxx / bg_toggle
These methods are used to control background light, for each command detail,
refer to set_xxx command.
Refer to C<set_xxx> command.
=head2 bg_adjust_xxx
This method is used to adjust background light by specified percentage within
specified duration.
Refer to C<adjust_bright>, C<adjust_ct>, C<adjust_color>.
=head2 dev_toggle
This method is used to toggle the main light and background light at the same
time.
=head1 AUTHOR
Jan Baier, C<< <jan.baier at amagical.net> >>
=head1 SEE ALSO
This API is described in the Yeeling WiFi Light Inter-Operation Specification.
=head1 LICENSE AND COPYRIGHT
Copyright 2019 Jan Baier.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See L<http://dev.perl.org/licenses/> for more information.
=cut
1; # End of Device::Yeelight