#############################################################
# This file was automatically generated on 2019-11-25.      #
#                                                           #
# Perl Bindings Version 2.1.25                              #
#                                                           #
# If you have a bugfix for this file and want to commit it, #
# please fix the bug in the generator. You can find a link  #
# to the generators git repository on tinkerforge.com       #
#############################################################

=pod

=encoding utf8

=head1 NAME

Tinkerforge::BrickletLEDStrip - Controls up to 320 RGB LEDs

=cut

package Tinkerforge::BrickletLEDStrip;

use strict;
use warnings;
use Carp;
use threads;
use threads::shared;
use parent 'Tinkerforge::Device';
use Tinkerforge::IPConnection;
use Tinkerforge::Error;

=head1 CONSTANTS

=over

=item DEVICE_IDENTIFIER

This constant is used to identify a LED Strip Bricklet.

The get_identity() subroutine and the CALLBACK_ENUMERATE callback of the
IP Connection have a device_identifier parameter to specify the Brick's or
Bricklet's type.

=cut

use constant DEVICE_IDENTIFIER => 231;

=item DEVICE_DISPLAY_NAME

This constant represents the display name of a LED Strip Bricklet.

=cut

use constant DEVICE_DISPLAY_NAME => 'LED Strip Bricklet';

=item CALLBACK_FRAME_RENDERED

This constant is used with the register_callback() subroutine to specify
the CALLBACK_FRAME_RENDERED callback.

=cut

use constant CALLBACK_FRAME_RENDERED => 6;

=item FUNCTION_SET_RGB_VALUES

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_RGB_VALUES => 1;

=item FUNCTION_GET_RGB_VALUES

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_RGB_VALUES => 2;

=item FUNCTION_SET_FRAME_DURATION

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_FRAME_DURATION => 3;

=item FUNCTION_GET_FRAME_DURATION

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_FRAME_DURATION => 4;

=item FUNCTION_GET_SUPPLY_VOLTAGE

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_SUPPLY_VOLTAGE => 5;

=item FUNCTION_SET_CLOCK_FREQUENCY

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_CLOCK_FREQUENCY => 7;

=item FUNCTION_GET_CLOCK_FREQUENCY

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_CLOCK_FREQUENCY => 8;

=item FUNCTION_SET_CHIP_TYPE

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_CHIP_TYPE => 9;

=item FUNCTION_GET_CHIP_TYPE

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_CHIP_TYPE => 10;

=item FUNCTION_SET_RGBW_VALUES

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_RGBW_VALUES => 11;

=item FUNCTION_GET_RGBW_VALUES

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_RGBW_VALUES => 12;

=item FUNCTION_SET_CHANNEL_MAPPING

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_SET_CHANNEL_MAPPING => 13;

=item FUNCTION_GET_CHANNEL_MAPPING

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_CHANNEL_MAPPING => 14;

=item FUNCTION_ENABLE_FRAME_RENDERED_CALLBACK

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_ENABLE_FRAME_RENDERED_CALLBACK => 15;

=item FUNCTION_DISABLE_FRAME_RENDERED_CALLBACK

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_DISABLE_FRAME_RENDERED_CALLBACK => 16;

=item FUNCTION_IS_FRAME_RENDERED_CALLBACK_ENABLED

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_IS_FRAME_RENDERED_CALLBACK_ENABLED => 17;

=item FUNCTION_GET_IDENTITY

This constant is used with the get_response_expected(), set_response_expected()
and set_response_expected_all() subroutines.

=cut

use constant FUNCTION_GET_IDENTITY => 255;
use constant CHIP_TYPE_WS2801 => 2801;
use constant CHIP_TYPE_WS2811 => 2811;
use constant CHIP_TYPE_WS2812 => 2812;
use constant CHIP_TYPE_LPD8806 => 8806;
use constant CHIP_TYPE_APA102 => 102;
use constant CHANNEL_MAPPING_RGB => 6;
use constant CHANNEL_MAPPING_RBG => 9;
use constant CHANNEL_MAPPING_BRG => 33;
use constant CHANNEL_MAPPING_BGR => 36;
use constant CHANNEL_MAPPING_GRB => 18;
use constant CHANNEL_MAPPING_GBR => 24;
use constant CHANNEL_MAPPING_RGBW => 27;
use constant CHANNEL_MAPPING_RGWB => 30;
use constant CHANNEL_MAPPING_RBGW => 39;
use constant CHANNEL_MAPPING_RBWG => 45;
use constant CHANNEL_MAPPING_RWGB => 54;
use constant CHANNEL_MAPPING_RWBG => 57;
use constant CHANNEL_MAPPING_GRWB => 78;
use constant CHANNEL_MAPPING_GRBW => 75;
use constant CHANNEL_MAPPING_GBWR => 108;
use constant CHANNEL_MAPPING_GBRW => 99;
use constant CHANNEL_MAPPING_GWBR => 120;
use constant CHANNEL_MAPPING_GWRB => 114;
use constant CHANNEL_MAPPING_BRGW => 135;
use constant CHANNEL_MAPPING_BRWG => 141;
use constant CHANNEL_MAPPING_BGRW => 147;
use constant CHANNEL_MAPPING_BGWR => 156;
use constant CHANNEL_MAPPING_BWRG => 177;
use constant CHANNEL_MAPPING_BWGR => 180;
use constant CHANNEL_MAPPING_WRBG => 201;
use constant CHANNEL_MAPPING_WRGB => 198;
use constant CHANNEL_MAPPING_WGBR => 216;
use constant CHANNEL_MAPPING_WGRB => 210;
use constant CHANNEL_MAPPING_WBGR => 228;
use constant CHANNEL_MAPPING_WBRG => 225;


=back

=head1 FUNCTIONS

=over

=item new()

Creates an object with the unique device ID *uid* and adds it to
the IP Connection *ipcon*.

=cut

sub new
{
	my ($class, $uid, $ipcon) = @_;

	my $self = Tinkerforge::Device->_new($uid, $ipcon, [2, 0, 3]);

	$self->{response_expected}->{&FUNCTION_SET_RGB_VALUES} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_RGB_VALUES} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_SET_FRAME_DURATION} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_FRAME_DURATION} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_GET_SUPPLY_VOLTAGE} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_SET_CLOCK_FREQUENCY} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_CLOCK_FREQUENCY} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_SET_CHIP_TYPE} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_CHIP_TYPE} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_SET_RGBW_VALUES} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_RGBW_VALUES} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_SET_CHANNEL_MAPPING} = Tinkerforge::Device->_RESPONSE_EXPECTED_FALSE;
	$self->{response_expected}->{&FUNCTION_GET_CHANNEL_MAPPING} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_ENABLE_FRAME_RENDERED_CALLBACK} = Tinkerforge::Device->_RESPONSE_EXPECTED_TRUE;
	$self->{response_expected}->{&FUNCTION_DISABLE_FRAME_RENDERED_CALLBACK} = Tinkerforge::Device->_RESPONSE_EXPECTED_TRUE;
	$self->{response_expected}->{&FUNCTION_IS_FRAME_RENDERED_CALLBACK_ENABLED} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;
	$self->{response_expected}->{&FUNCTION_GET_IDENTITY} = Tinkerforge::Device->_RESPONSE_EXPECTED_ALWAYS_TRUE;

	$self->{callback_formats}->{&CALLBACK_FRAME_RENDERED} = 'S';



	bless($self, $class);

	return $self;
}


=item set_rgb_values()

Sets *length* RGB values for the LEDs starting from *index*.

To make the colors show correctly you need to configure the chip type
(:func:`Set Chip Type`) and a 3-channel channel mapping (:func:`Set Channel Mapping`)
according to the connected LEDs.

Example: If you set

* index to 5,
* length to 3,
* r to [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
* g to [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] and
* b to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

the LED with index 5 will be red, 6 will be green and 7 will be blue.

.. note:: Depending on the LED circuitry colors can be permuted.

The colors will be transfered to actual LEDs when the next
frame duration ends, see :func:`Set Frame Duration`.

Generic approach:

* Set the frame duration to a value that represents
  the number of frames per second you want to achieve.
* Set all of the LED colors for one frame.
* Wait for the :cb:`Frame Rendered` callback.
* Set all of the LED colors for next frame.
* Wait for the :cb:`Frame Rendered` callback.
* and so on.

This approach ensures that you can change the LED colors with
a fixed frame rate.

The actual number of controllable LEDs depends on the number of free
Bricklet ports. See :ref:`here <led_strip_bricklet_ram_constraints>` for more
information. A call of :func:`Set RGB Values` with index + length above the
bounds is ignored completely.

=cut

sub set_rgb_values
{
	my ($self, $index, $length, $r, $g, $b) = @_;

	$self->_send_request(&FUNCTION_SET_RGB_VALUES, [$index, $length, $r, $g, $b], 'S C C16 C16 C16', '');
}

=item get_rgb_values()

Returns *length* R, G and B values starting from the
given LED *index*.

The values are the last values that were set by :func:`Set RGB Values`.

=cut

sub get_rgb_values
{
	my ($self, $index, $length) = @_;

	return $self->_send_request(&FUNCTION_GET_RGB_VALUES, [$index, $length], 'S C', 'C16 C16 C16');
}

=item set_frame_duration()

Sets the frame duration.

Example: If you want to achieve 20 frames per second, you should
set the frame duration to 50ms (50ms * 20 = 1 second).

For an explanation of the general approach see :func:`Set RGB Values`.

=cut

sub set_frame_duration
{
	my ($self, $duration) = @_;

	$self->_send_request(&FUNCTION_SET_FRAME_DURATION, [$duration], 'S', '');
}

=item get_frame_duration()

Returns the frame duration as set by :func:`Set Frame Duration`.

=cut

sub get_frame_duration
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_FRAME_DURATION, [], '', 'S');
}

=item get_supply_voltage()

Returns the current supply voltage of the LEDs.

=cut

sub get_supply_voltage
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_SUPPLY_VOLTAGE, [], '', 'S');
}

=item set_clock_frequency()

Sets the frequency of the clock.

The Bricklet will choose the nearest achievable frequency, which may
be off by a few Hz. You can get the exact frequency that is used by
calling :func:`Get Clock Frequency`.

If you have problems with flickering LEDs, they may be bits flipping. You
can fix this by either making the connection between the LEDs and the
Bricklet shorter or by reducing the frequency.

With a decreasing frequency your maximum frames per second will decrease
too.

.. note::
 The frequency in firmware version 2.0.0 is fixed at 2MHz.

.. versionadded:: 2.0.1$nbsp;(Plugin)

=cut

sub set_clock_frequency
{
	my ($self, $frequency) = @_;

	$self->_send_request(&FUNCTION_SET_CLOCK_FREQUENCY, [$frequency], 'L', '');
}

=item get_clock_frequency()

Returns the currently used clock frequency as set by :func:`Set Clock Frequency`.

.. versionadded:: 2.0.1$nbsp;(Plugin)

=cut

sub get_clock_frequency
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_CLOCK_FREQUENCY, [], '', 'L');
}

=item set_chip_type()

Sets the type of the LED driver chip. We currently support the chips

* WS2801,
* WS2811,
* WS2812 / SK6812 / NeoPixel RGB,
* SK6812RGBW / NeoPixel RGBW (Chip Type = WS2812),
* LPD8806 and
* APA102 / DotStar.

.. versionadded:: 2.0.2$nbsp;(Plugin)

=cut

sub set_chip_type
{
	my ($self, $chip) = @_;

	$self->_send_request(&FUNCTION_SET_CHIP_TYPE, [$chip], 'S', '');
}

=item get_chip_type()

Returns the currently used chip type as set by :func:`Set Chip Type`.

.. versionadded:: 2.0.2$nbsp;(Plugin)

=cut

sub get_chip_type
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_CHIP_TYPE, [], '', 'S');
}

=item set_rgbw_values()

Sets *length* RGBW values for the LEDs starting from *index*.

To make the colors show correctly you need to configure the chip type
(:func:`Set Chip Type`) and a 4-channel channel mapping (:func:`Set Channel Mapping`)
according to the connected LEDs.

The maximum length is 12, the index goes from 0 to 239 and the rgbw values
have 8 bits each.

Example: If you set

* index to 5,
* length to 4,
* r to [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
* g to [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
* b to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0] and
* w to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0]

the LED with index 5 will be red, 6 will be green, 7 will be blue and 8 will be white.

.. note:: Depending on the LED circuitry colors can be permuted.

The colors will be transfered to actual LEDs when the next
frame duration ends, see :func:`Set Frame Duration`.

Generic approach:

* Set the frame duration to a value that represents
  the number of frames per second you want to achieve.
* Set all of the LED colors for one frame.
* Wait for the :cb:`Frame Rendered` callback.
* Set all of the LED colors for next frame.
* Wait for the :cb:`Frame Rendered` callback.
* and so on.

This approach ensures that you can change the LED colors with
a fixed frame rate.

The actual number of controllable LEDs depends on the number of free
Bricklet ports. See :ref:`here <led_strip_bricklet_ram_constraints>` for more
information. A call of :func:`Set RGBW Values` with index + length above the
bounds is ignored completely.

The LPD8806 LED driver chips have 7-bit channels for RGB. Internally the LED
Strip Bricklets divides the 8-bit values set using this function by 2 to make
them 7-bit. Therefore, you can just use the normal value range (0-255) for
LPD8806 LEDs.

The brightness channel of the APA102 LED driver chips has 5-bit. Internally the
LED Strip Bricklets divides the 8-bit values set using this function by 8 to make
them 5-bit. Therefore, you can just use the normal value range (0-255) for
the brightness channel of APA102 LEDs.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub set_rgbw_values
{
	my ($self, $index, $length, $r, $g, $b, $w) = @_;

	$self->_send_request(&FUNCTION_SET_RGBW_VALUES, [$index, $length, $r, $g, $b, $w], 'S C C12 C12 C12 C12', '');
}

=item get_rgbw_values()

Returns *length* RGBW values starting from the given *index*.

The values are the last values that were set by :func:`Set RGBW Values`.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub get_rgbw_values
{
	my ($self, $index, $length) = @_;

	return $self->_send_request(&FUNCTION_GET_RGBW_VALUES, [$index, $length], 'S C', 'C12 C12 C12 C12');
}

=item set_channel_mapping()

Sets the channel mapping for the connected LEDs.

:func:`Set RGB Values` and :func:`Set RGBW Values` take the data in RGB(W) order.
But the connected LED driver chips might have their 3 or 4 channels in a
different order. For example, the WS2801 chips typically use BGR order, the
WS2812 chips typically use GRB order and the APA102 chips typically use WBGR
order.

The APA102 chips are special. They have three 8-bit channels for RGB
and an additional 5-bit channel for the overall brightness of the RGB LED
making them 4-channel chips. Internally the brightness channel is the first
channel, therefore one of the Wxyz channel mappings should be used. Then
the W channel controls the brightness.

If a 3-channel mapping is selected then :func:`Set RGB Values` has to be used.
Calling :func:`Set RGBW Values` with a 3-channel mapping will produce incorrect
results. Vice-versa if a 4-channel mapping is selected then
:func:`Set RGBW Values` has to be used. Calling :func:`Set RGB Values` with a
4-channel mapping will produce incorrect results.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub set_channel_mapping
{
	my ($self, $mapping) = @_;

	$self->_send_request(&FUNCTION_SET_CHANNEL_MAPPING, [$mapping], 'C', '');
}

=item get_channel_mapping()

Returns the currently used channel mapping as set by :func:`Set Channel Mapping`.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub get_channel_mapping
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_CHANNEL_MAPPING, [], '', 'C');
}

=item enable_frame_rendered_callback()

Enables the :cb:`Frame Rendered` callback.

By default the callback is enabled.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub enable_frame_rendered_callback
{
	my ($self) = @_;

	$self->_send_request(&FUNCTION_ENABLE_FRAME_RENDERED_CALLBACK, [], '', '');
}

=item disable_frame_rendered_callback()

Disables the :cb:`Frame Rendered` callback.

By default the callback is enabled.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub disable_frame_rendered_callback
{
	my ($self) = @_;

	$self->_send_request(&FUNCTION_DISABLE_FRAME_RENDERED_CALLBACK, [], '', '');
}

=item is_frame_rendered_callback_enabled()

Returns *true* if the :cb:`Frame Rendered` callback is enabled, *false* otherwise.

.. versionadded:: 2.0.6$nbsp;(Plugin)

=cut

sub is_frame_rendered_callback_enabled
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_IS_FRAME_RENDERED_CALLBACK_ENABLED, [], '', '?');
}

=item get_identity()

Returns the UID, the UID where the Bricklet is connected to,
the position, the hardware and firmware version as well as the
device identifier.

The position can be 'a', 'b', 'c' or 'd'.

The device identifier numbers can be found :ref:`here <device_identifier>`.
|device_identifier_constant|

=cut

sub get_identity
{
	my ($self) = @_;

	return $self->_send_request(&FUNCTION_GET_IDENTITY, [], '', 'Z8 Z8 a C3 C3 S');
}

=back
=cut

1;
