########################################################################################################################
# Hue.pm
#-----------------------------------------------------------------------------------------------------------------------
#
# Kommunikation mit der Philips Hue Bridge
#
# Bei farbige Lampen, welche Bauart bedingt keine Einstellung der Farbtemperatur zulassen kann trozdem die
# Farbtemperatur eingestellt werden. hierzu wurde ein Mapping der Temperaturangabe auf die xy-Farbskala integriert.
#
# Fehlt noch:
# - Implementierung Schedules API
# - Implementierung Scenes API
# - Implementierung Senors API
# - Implementierung Configuration API
#
#
# Getestete Geräte:
# Philips LCA001 White and Color ambiance
# Ikea TRADFRI bulb E27 CWS opal 600lm (Color)
# Ikea TRADFRI bulb E14 CWS opal 600lm (Color)
# Osram CLA 60 RGBW
# Osram CLB 40 Tunable White
# Innr RB 250 C (RGBW)
# FLAIR VIYU-C35-470-CCT-10011722 (Tunable White)
# Ledvance Smart+ Outdoor Plug EU
#
#
# Aufruf           : use TSS::Philips::Hue;
#
#                    Neuen Öffentlicher Schlüssel erzeugen:
#                    --------------------------------------
#                    my $gobjGateway = TSS::Philips::Hue->new( host => "<IP-Adresse>", username => "<Benutzername>" );
#                    print "Gateway-Code: ".$gobjGateway->{"presharedkey"}."\n";
#
#                    Genereller Aufruf:
#                    ------------------
#                    my $gobjGateway = TSS::Philips::Hue->new( host => "<IP-Adresse>", presharedkey => "<Gateway-Code>" );
#
#                    Version ausgeben:
#                    -----------------
#                    print "Version: ".$TSS::Philips::Hue::VERSION."\n";
#         
#                    Alle Geräte auflisten:
#                    ----------------------
#                    my $gprtarrDevices=$gobjGateway->listObjects();
#                    if (! defined($gprtarrDevices)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    foreach my $tobjDevice ( @{$gprtarrDevices} ) { print $tobjDevice."\n"; }
#                      > <datapoint deviceid='phl1' name='Color light 1ä' devicetype='TRADFRI bulb E27 CWS opal 600lm' online='0' status='0' brightness='131' ct='345' xyY='0.4444,0.4065,131' hsv='8418,140,254' />
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='0' status='0' brightness='131' ct='500' xyY='0.5266,0.4133,131' hsv='8418,140,254' />
#
#                    Geräteinformationen ausgeben:
#                    -----------------------------
#                    my $gobjDevice=$gobjGateway->getDeviceInfo("phl2"); # phl2=Device-ID;
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='0' status='0' brightness='131' ct='500' xyY='0.5266,0.4133,131' hsv='8418,140,254' />
#
#                    Alle Geräte aus-/einschalten:
#                    -----------------------------
#                    my $gstrResult=$gobjGateway->setPowerAll(0); # 0=aus, 1=ein
#                    if (! $gstrResult) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "Befehl erfolgreich!\n"; }
#                    print $gstrResult."\n";
#                      > <datapoint deviceid='' status='0' />
#
#                    Alle Lampen aus-/einschalten:
#                    -----------------------------
#                    my $gstrResult=$gobjGateway->setPowerAllLights(0); # 0=aus, 1=ein
#                    if (! $gstrResult) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "Befehl erfolgreich!\n"; }
#                    print $gstrResult."\n";
#                      > <datapoint deviceid='' status='0' />
#
#                    Alle Steckdosen aus-/einschalten:
#                    ---------------------------------
#                    my $gstrResult=$gobjGateway->setPowerAllPlugs(0); # 0=aus, 1=ein
#                    if (! $gstrResult) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "Befehl erfolgreich!\n"; }
#                    print $gstrResult."\n";
#                      > <datapoint deviceid='' status='1' />
#
#                    Alle Gruppen aus-/einschalten:
#                    ------------------------------
#                    my $gstrResult=$gobjGateway->setPowerAllGroups(0); # 0=aus, 1=ein
#                    if (! $gstrResult) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "Befehl erfolgreich!\n"; }
#                    print $gstrResult."\n";
#                      > <datapoint deviceid='' status='0' />
#         
#                    Ein Gerät aus-/einschalten:
#                    ---------------------------
#                    my $gobjDevice=$gobjGateway->setPower("phl2",0); # phl2=Device-ID; 0=aus, 1=ein
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='1' status='1' brightness='254' ct='366' xyY='0.4573,0.41,254' hsv='8418,140,254' />
#                    print $gobjDevice->status()."\n";
#                      > <datapoint deviceid='phl2' status='1' />
#
#                    Helligkeit eines Gerätes steuern:
#                    ---------------------------------
#                    my $gobjDevice=$gobjGateway->setBrightness("phl2",100); # phl2=Device-ID; 0-254=Helligkeit
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='1' status='1' brightness='120' ct='366' xyY='0.4573,0.41,120' hsv='8418,140,254' />
#                    print $gobjDevice->brightness()."\n";
#                      > <datapoint deviceid='phl2' brightness='120' />
#
#                    Farbtemperatur eines Gerätes steuern:
#                    -------------------------------------
#                    my $gobjDevice=$gobjGateway->setCT("phl2",1); # phl2=Device-ID; 153-500=Farbtemperatur
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                         else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='1' status='1' brightness='120' ct='366' xyY='0.4572,0.4099,120' hsv='8418,140,254' />
#                    print $gobjDevice->ct()."\n";
#                      > <datapoint deviceid='phl2' ct='366' />
#
#                    Farbe eines Gerätes über xyY-Wert ändern:
#                    -----------------------------------------
#                    my $gobjDevice=$gobjGateway->setXYY("phl2","0.4572,0.4099,120"); # phl2=Device-ID; "0-1,0-1,0-254"=xyY-Wert
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='1' status='1' brightness='64' ct='366' xyY='0.64,0.33,64' hsv='8418,140,254' />
#                    print $gobjDevice->xyy()."\n";
#                      > <datapoint deviceid='phl2' xyY='0.64,0.33,64' />
#
#                    Farbe eines Gerätes über HSV-Wert ändern:
#                    -----------------------------------------
#                    my $gobjDevice=$gobjGateway->setHsv("phl2","8595,121,120"); # phl2=Device-ID; "0-65535,0-254,0-254"=HSV-Wert
#                    if (! defined($gobjDevice)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                    else { print "$gobjDevice\n"; }
#                      > <datapoint deviceid='phl2' name='Hue color lamp 1' devicetype='LCA001' online='1' status='1' brightness='120' ct='343' xyY='0.6915,0.3083,120' hsv='0,254,120' />
#                    print $gobjDevice->xyy()."\n";
#                      > <datapoint deviceid='phl2' xyY='0.6915,0.3083,120' />
#
# Attribute        : Fehlertext   = $lobjSelf->{"error"}
#                    IP-Adresse   = $lobjSelf->{"host"}
#                    Benutzername = $lobjSelf->{"username"}
#                    Gateway-Key  = $lobjSelf->{"presharedkey"}
#
# Methoden         : Alle Geräte ausgeben                              = $objGateway->listObjects()
#                    Geräteinformationen ausgeben                      = $objGateway->getDeviceInfo(<Geräte-ID>)
#                    Alle Geräte schalten                              = $objGateway->setPowerAll(<Status>)                    -> <Status>     : 0=aus, 1=ein
#                    Alle Lampen schalten                              = $objGateway->setPowerAllLights(<Status>)              -> <Status>     : 0=aus, 1=ein
#                    Alle Steckdosen schalten                          = $objGateway->setPowerAllPlugs(<Status>)               -> <Status>     : 0=aus, 1=ein
#                    Alle Gruppen schalten                             = $objGateway->setPowerAllGroups(<Status>)              -> <Status>     : 0=aus, 1=ein
#                    Ein Gerät schalten                                = $objGateway->setPower(<Geräte-ID>,<Status>)           -> <Status>     : 0=aus, 1=ein
#                    Helligkeit eines Gerätes steuern                  = $objGateway->setBrightness(<Geräte-ID>,<Helligkeit>)  -> <Helligkeit> : 0-254=Helligkeit
#                    Farbtemperatur eines Gerätes über ct-Wert steuern = $objGateway->setCT(<Geräte-ID>,<Temperatur>)          -> <Temperatur> : 153-500=Temperatur
#                    Farbe eines Gerätes über xyY-Wert ändern          = $objGateway->setXYY(<Geräte-ID>,<Farbe>)              -> <Farbe>      : 0-1,0-1,0-254=x,y,Y
#                    Farbe eines Gerätes über HSV-Wert ändern          = $objGateway->setHsv(<Geräte-ID>,<Farbe>)              -> <Farbe>      : 0-65535,0-254,0-254=H,S,V
#
# Präfixe Device-ID: phl Leuchten   (l=light)
#                    php Steckdosen (p=Plug)
#                    phg Gruppen    (g=group)
#
# Version          : 17.12.2019 v1.0.0 Initiale Version
#                    20.12.2019 v1.0.1 Namensangelichungen mit anderen Modulen
#                    07.01.2020 v1.0.2 Erweiterung um Steckdosen
#                    04.02.2020 v1.0.3 Copyright und Warranty hinzugefügt
#
#
# Copyright & Warranty:
# =====================
#
# Copyright (C) 2019 Thomas Schütz-Schneider 
#
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 
#
# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. 
#
########################################################################################################################


# ========================
#  Package-Name
# ========================
package TSS::Philips::Hue;

# ========================
#  Definition der Pragmas
# ========================
use strict;
use warnings;
use LWP::Simple;
use LWP::UserAgent;
use JSON::Parse 'parse_json';
use TSS::Philips::Hue::Light;
use TSS::Philips::Hue::Group;

# ==================================
#  Definition der Versions-Variable
# ==================================
our $VERSION = "v1.0.3";


########################################################################################################################
# Konstruktur
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : use TSS::Philips::Hue;
#           $objGateway = TSS::Philips::Hue->new( host => <IP-Adresse>, username => <Benutzername> | presharedkey => <Öffentlicher Schlüssel> );
#
# Übergabe: <IP-Adresse>             = IP-Adrese der Hue Bridge
#           <Benutzername>           = Benutzername des öffentlichen Schlüssels
#           <Öffentlicher Schlüssel> = Öffentlicher Schlüssel zur Kommunikation mit der Hue Bridge
#
# Rückgabe: $objGateway              = Hue Bridge
#
#-----------------------------------------------------------------------------------------------------------------------
sub new {
  my $lobjClass=shift; # Klasse-Name abfangen
  my $lobjSelf={};     # Klassen-Attribute
  my $lptrResult="";   # Zeiger auf Objekt mit dekdierten JSON-Sting

  # Korrekte Referenzierung auf den Klasse-Name
  $lobjClass = ref($lobjClass) || $lobjClass;
  
  # Parameter übernemen
  my %lhshParameter = (@_);
  
  # Attribute der Klasse erzeugen
  # Enthält im Fehlerfall in einer Subroutine die Fehlerbeschreibung
  $lobjSelf->{"error"}="";
  # IP-Adresse der Hue Bridge
  $lobjSelf->{"host"} = $lhshParameter{'host'} || die "Fehlender Parameter \"host\"!";
  # Benutzername der Hue Bridge
  $lobjSelf->{"username"} = $lhshParameter{'username'} || die "Fehlender Parameter \"username\"!";
  # Öffentlicher Schlüssel der Hue Bridge
  $lobjSelf->{"presharedkey"} = $lhshParameter{'presharedkey'};
  # Prüfen ob Gateway-Code oder Öffentlicher Schlüssel vorhanden ist
  if (($lobjSelf->{'username'} eq "") && ($lobjSelf->{'presharedkey'} eq "")) { die "Fehlender Parameter \"username/presharedkey\"!"; }
    
  # Klasse erzeugen
  bless( $lobjSelf, $lobjClass );
  
  # Prüfen ob kein Öffentlicher Schlüssel vorhanden ist
  if ($lobjSelf->{'presharedkey'} eq "") {
    # Öffentlicher Schlüssel Anfragen
    my $tstrResponse=$lobjSelf->_requestPresharedKey("{\"devicetype\":\"".$lobjSelf->{"username"}."\"}");
    # Fehlerüberprüfung
    if (!defined($tstrResponse)) { die "NIX!".$lobjSelf->{"error"}; }
    # Überprüfen on der Button der Hue Bridge nicht gedrückt wurde
    if ($tstrResponse =~ /link button not pressed/) { die "Bitte zuerst den Button an der Hue Bridge drücken!"; }
    # JSON-String dekodieren
    $lptrResult=parse_json($tstrResponse);
    # Unerwaretetes Ergebnis?
    if (ref($lptrResult) ne "ARRAY") { die "Unerwartetes Ergebnisformat (".ref($lptrResult).") !"; }
    if (!defined($lptrResult->[0]{"success"}{"username"})) { die "Keinen Öffentlicher Schlüssel erhalten!"; }
    # Öffentlicher Schlüssel der Hue Bridge übernehmen 
    $lobjSelf->{"presharedkey"}=$lptrResult->[0]{"success"}{"username"};
  }

  # Klasse zurück geben
  return($lobjSelf);
}
########################################################################################################################


########################################################################################################################
# Einen neuen Gateway-Code erzeugen
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->_requestPresharedKey($strBody);
#
# Übergabe: $strBody     = Auszuführende Aufgabe im HTML-Body als Json-String
#
# Rückgabe: $strResponse = Json-String=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _requestPresharedKey {
  my $lobjSelf=shift;      # Klasse-Name abfangen
  my $lstrBody=shift;      # Auszuführende Aufgabe
  my $lobjHttpRequest=();  # HTTP-Request-Objekt
  my $lobjLwpUserAgent=(); # LWP-UserAgent-Objekt
  my $lobjHttpResponse=(); # HTTP-Response-Objekt
  my $lstrResponse="";     # Antwort der Hue Bridge
  
  $lobjHttpRequest = HTTP::Request->new( "POST", "http://".$lobjSelf->{"host"}."/api" );
  $lobjHttpRequest->header('Content-Type' => 'application/json');
  $lobjHttpRequest->content($lstrBody);
  $lobjLwpUserAgent = LWP::UserAgent->new;
  $lobjHttpResponse = $lobjLwpUserAgent->request( $lobjHttpRequest );
  if ($lobjHttpResponse->is_success) { $lstrResponse=$lobjHttpResponse->decoded_content; }
  else { $lobjSelf->{"error"}="Hue Bridge: Abfrage nicht erfolgreich (".$lobjHttpResponse->status_line.")!"; return; }

  # Rückmeldung
  return($lstrResponse);
}
########################################################################################################################


########################################################################################################################
# Kommunikation mit der Hue Bridge
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->_requestGateway($intMethod,$strUrl,$strBody);
#
# Übergabe: $intMethod   = Methode (0=get, 1=put, 2=post, 3=delete)
#           $strUrl      = URL des Gerätes
#           $strBody     = Auszuführende Aufgabe im HTML-Body als Json-String
#
# Rückgabe: $strResponse = Json-String=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _requestGateway {
  my $lobjSelf=shift;      # Klasse-Name abfangen
  my $lintMethod=shift;    # Methode (0=GET, 1=PUT, 2=POST, 3=DELETE)
  my $lstrUrl=shift;       # URL des Gerätes
  my $lstrBody=shift;      # Auszuführende Aufgabe
  my $lstrMethod="";       # Methode
  my $lobjHttpRequest=();  # HTTP-Request-Objekt
  my $lobjLwpUserAgent=(); # LWP-UserAgent-Objekt
  my $lobjHttpResponse=(); # HTTP-Response-Objekt
  my $lstrResponse="";     # Antwort der Hue Bridge

  # Methode dekodieren
  if ($lintMethod == 0) { $lstrMethod="GET"; }
  elsif ($lintMethod == 1) { $lstrMethod="PUT"; }
  elsif ($lintMethod == 2) { $lstrMethod="POST"; }
  elsif ($lintMethod == 3) { $lstrMethod="DELETE"; }
  else  { $lstrMethod="GET"; }
  
  $lobjHttpRequest = HTTP::Request->new( $lstrMethod, "http://".$lobjSelf->{"host"}."/api/".$lobjSelf->{"presharedkey"}.$lstrUrl );
  $lobjHttpRequest->header('Content-Type' => 'application/json');
  $lobjHttpRequest->content($lstrBody);
  $lobjLwpUserAgent = LWP::UserAgent->new;
  $lobjHttpResponse = $lobjLwpUserAgent->request( $lobjHttpRequest );
  if ($lobjHttpResponse->is_success) { $lstrResponse=$lobjHttpResponse->decoded_content; }
  else { $lobjSelf->{"error"}="Hue Bridge: Abfrage nicht erfolgreich (".$lobjHttpResponse->status_line.")!"; return; }

  # Rückmeldung
  return($lstrResponse);
}
########################################################################################################################


########################################################################################################################
# Liste der vorhandenen realen Objekt-ID's (ohne führendes "phX") ermitteln
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $ptrArray=$objGateway->_getAllRealObjectIds();
#
# Übergabe: -
#
# Rückgabe: $ptrArray = Zeiger auf Array=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _getAllRealObjectIds {
  my $lobjSelf=shift;  # Klasse-Name abfangen
  my $lstrResponse=""; # Antwort der Hue Bridge
  my $lptrResult="";   # Zeiger auf ein Array, Hash oder Sclar eines dekodierten JSON-Strings
  my @larrDeviceId=(); # Geräte-ID's
  
  # Kommunikation mit der Hue Bridge ->Geräteliste ausgeben
  $lstrResponse=$lobjSelf->_requestGateway(0,"","");

  # Ist ein Fehler aufgetreten?
  if (!defined($lstrResponse)) { return; }
  
  # JSON-String dekodieren
  $lptrResult=parse_json($lstrResponse);
  
  # Unerwaretetes Ergebnis?
  if (ref($lptrResult) ne "HASH") { $lobjSelf->{"error"}="_getAllRealObjectIds: Unerwartetes Ergebnisformat (".ref($lptrResult).") !"; return; }
  
  # Alle Typen bearbeiten
  foreach my $lstrType (sort { $a cmp $b } keys %{$lptrResult}) {
    # Lampen/Steckdosen
    if ($lstrType eq "lights") {
      foreach my $tstrID  (keys %{$lptrResult->{$lstrType}}) {
        if (lc($lptrResult->{$lstrType}{$tstrID}{'type'}) =~ /on\/off plug/) { push(@larrDeviceId,"php".$tstrID); }
        else { push(@larrDeviceId,"phl".$tstrID); }
      }
    }
    # Gruppen
    if ($lstrType eq "groups") { foreach my $tstrID  (keys %{$lptrResult->{$lstrType}}) { push(@larrDeviceId,"phg".$tstrID); } }
  }

  # Erfolgreicher Rückmeldung
  return(\@larrDeviceId);
}
########################################################################################################################


########################################################################################################################
# Überprüfen ob ein Hue Gerät vorhanden ist
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResult=$objGateway->_checkObject($strEndpoint,$strAddress);
#
# Übergabe: $strAddress  = Geräte-ID (phl2)
#
# Rückgabe: $strResult   = JSON-String mit Gerätedaten=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _checkObject {
  my $lobjSelf=shift;     # Klasse-Name abfangen
  my $lstrAddress=shift;  # Geräte-ID (phl2)
  my $lptrResult="";      # Zeiger auf ein Array mit Geräte-ID's
  my $lstrRealAddr="";    # Geräte-ID ohne führendes "phX" (2)
  my %lhshDeviceIds=();   # Vorhandene reale Geräte-ID ohne führendes "phX" (2) 
  my $lstrResponse="";    # Antwort der Hue Bridge

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Liste der vorhandenen realen Geräte-ID's (ohne führendes "itfX") ermitteln
  $lptrResult=$lobjSelf->_getAllRealObjectIds();
  if (! defined($lptrResult)) { return; }

  # Wurden keine Geräte/Gruppen gefunden?
  if (scalar(@{$lptrResult}) < 1) { return; }

  # Array in Hash umwandlen
  $lhshDeviceIds{$_}++ for (@{$lptrResult});
  
  # Geräte-ID in reale Geräte-ID umwandeln
  $lstrRealAddr=$lstrAddress;
  $lstrRealAddr=~s/^ph.//;
  
  # Überprüfen ob das gewünsche Gerät/Gruppe nicht vorhanden ist
  if (!defined($lhshDeviceIds{$lstrAddress})) { $lobjSelf->{"error"}="_checkObject: Gerät '$lstrAddress' ist nicht vorhanden!"; return; }

  # Alle Geräteinformationen von Lampen/Steckdosen auslesen
  if (($lstrAddress =~ /^phl/) || ($lstrAddress =~ /^php/)) {
    $lstrResponse=$lobjSelf->_requestGateway(0,"/lights/".$lstrRealAddr,"");
    # Ist ein Fehler aufgetreten?
    if (!defined($lstrResponse)) { return; }
  }
  # Alle Geräteinformationen von Gruppen auslesen
  elsif ($lstrAddress =~ /^phg/) {
    $lstrResponse=$lobjSelf->_requestGateway(0,"/groups/".$lstrRealAddr,"");
    # Ist ein Fehler aufgetreten?
    if (!defined($lstrResponse)) { return; }
  }
  else { $lobjSelf->{"error"}="_checkObject: Gerät '$lstrAddress' hat einen unbekannten Typ!"; return; }

  # Erfolgreiche Rückmeldung
  return($lstrResponse);
}
########################################################################################################################


########################################################################################################################
# ct-Temperatur in xy-Wert umrechen
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strValuexy=$objGateway->_ct2xy($intValueCt);
#
# Übergabe: $intValueCt = ct-Wert der Farbtemperatur
#
# Rückgabe: $strValuexy = xy-Wert der Farbtemperatur=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _ct2xy {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $tintValueCt=shift; # ct-Wert der Farbtemperatur
  my $tstrValuexy="";    # xy-Wert der Farbtemperatur
  if ($tintValueCt < 154) { $tstrValuexy="0.3122,0.3282"; }
  elsif ($tintValueCt < 164) { $tstrValuexy="0.3136,0.3295"; }
  elsif ($tintValueCt < 174) { $tstrValuexy="0.3206,0.3356"; }
  elsif ($tintValueCt < 184) { $tstrValuexy="0.3276,0.3417"; }
  elsif ($tintValueCt < 194) { $tstrValuexy="0.3347,0.3473"; }
  elsif ($tintValueCt < 204) { $tstrValuexy="0.3419,0.353"; }
  elsif ($tintValueCt < 214) { $tstrValuexy="0.349,0.3584"; }
  elsif ($tintValueCt < 224) { $tstrValuexy="0.3562,0.3633"; }
  elsif ($tintValueCt < 234) { $tstrValuexy="0.3634,0.3684"; }
  elsif ($tintValueCt < 244) { $tstrValuexy="0.3705,0.3728"; }
  elsif ($tintValueCt < 254) { $tstrValuexy="0.3776,0.3772"; }
  elsif ($tintValueCt < 264) { $tstrValuexy="0.3846,0.3812"; }
  elsif ($tintValueCt < 274) { $tstrValuexy="0.3916,0.385"; }
  elsif ($tintValueCt < 284) { $tstrValuexy="0.3986,0.3888"; }
  elsif ($tintValueCt < 294) { $tstrValuexy="0.4053,0.3918"; }
  elsif ($tintValueCt < 304) { $tstrValuexy="0.4121,0.3949"; }
  elsif ($tintValueCt < 314) { $tstrValuexy="0.4187,0.3977"; }
  elsif ($tintValueCt < 324) { $tstrValuexy="0.4252,0.4001"; }
  elsif ($tintValueCt < 334) { $tstrValuexy="0.4317,0.4026"; }
  elsif ($tintValueCt < 344) { $tstrValuexy="0.438,0.4045"; }
  elsif ($tintValueCt < 354) { $tstrValuexy="0.4444,0.4065"; }
  elsif ($tintValueCt < 364) { $tstrValuexy="0.4505,0.4083"; }
  elsif ($tintValueCt < 374) { $tstrValuexy="0.4565,0.4097"; }
  elsif ($tintValueCt < 384) { $tstrValuexy="0.4626,0.4112"; }
  elsif ($tintValueCt < 394) { $tstrValuexy="0.4684,0.4122"; }
  elsif ($tintValueCt < 404) { $tstrValuexy="0.4741,0.4132"; }
  elsif ($tintValueCt < 414) { $tstrValuexy="0.4797,0.4139"; }
  elsif ($tintValueCt < 424) { $tstrValuexy="0.4852,0.4145"; }
  elsif ($tintValueCt < 434) { $tstrValuexy="0.4906,0.415"; }
  elsif ($tintValueCt < 444) { $tstrValuexy="0.4957,0.4151"; }
  elsif ($tintValueCt < 454) { $tstrValuexy="0.5008,0.4152"; }
  elsif ($tintValueCt < 464) { $tstrValuexy="0.5058,0.4151"; }
  elsif ($tintValueCt < 474) { $tstrValuexy="0.5106,0.4149"; }
  elsif ($tintValueCt < 484) { $tstrValuexy="0.5154,0.4146"; }
  elsif ($tintValueCt < 492) { $tstrValuexy="0.5199,0.4141"; }
  elsif ($tintValueCt < 497) { $tstrValuexy="0.5245,0.4136"; }
  else { $tstrValuexy="0.5267,0.4133"; }
  return($tstrValuexy);
}
########################################################################################################################


########################################################################################################################
# xy-Temperatur in ct-Wert umrechen
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $intValueCt=$objGateway->_xy2ct($strValuexy);
#
# Übergabe: $strValuexy = xy-Wert der Farbtemperatur
#
# Rückgabe: $intValueCt = ct-Wert der Farbtemperatur=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub _xy2ct {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $tstrValuexy=shift; # xy-Wert der Farbtemperatur
  my $tintValueCt=153;   # ct-Wert der Farbtemperatur

  if ($tstrValuexy eq "0.3122,0.3282") { $tintValueCt=153; }
  elsif ($tstrValuexy eq "0.3136,0.3295") { $tintValueCt=155; }
  elsif ($tstrValuexy eq "0.3206,0.3356") { $tintValueCt=165; }
  elsif ($tstrValuexy eq "0.3276,0.3417") { $tintValueCt=175; }
  elsif ($tstrValuexy eq "0.3347,0.3473") { $tintValueCt=185; }
  elsif ($tstrValuexy eq "0.3419,0.353") { $tintValueCt=195; }
  elsif ($tstrValuexy eq "0.349,0.3584") { $tintValueCt=205; }
  elsif ($tstrValuexy eq "0.3562,0.3633") { $tintValueCt=215; }
  elsif ($tstrValuexy eq "0.3634,0.3684") { $tintValueCt=225; }
  elsif ($tstrValuexy eq "0.3705,0.3728") { $tintValueCt=235; }
  elsif ($tstrValuexy eq "0.3776,0.3772") { $tintValueCt=245; }
  elsif ($tstrValuexy eq "0.3846,0.3812") { $tintValueCt=255; }
  elsif ($tstrValuexy eq "0.3916,0.385") { $tintValueCt=265; }
  elsif ($tstrValuexy eq "0.3986,0.3888") { $tintValueCt=275; }
  elsif ($tstrValuexy eq "0.4053,0.3918") { $tintValueCt=285; }
  elsif ($tstrValuexy eq "0.4121,0.3949") { $tintValueCt=295; }
  elsif ($tstrValuexy eq "0.4187,0.3977") { $tintValueCt=305; }
  elsif ($tstrValuexy eq "0.4252,0.4001") { $tintValueCt=315; }
  elsif ($tstrValuexy eq "0.4317,0.4026") { $tintValueCt=325; }
  elsif ($tstrValuexy eq "0.438,0.4045") { $tintValueCt=335; }
  elsif ($tstrValuexy eq "0.4444,0.4065") { $tintValueCt=345; }
  elsif ($tstrValuexy eq "0.4505,0.4083") { $tintValueCt=355; }
  elsif ($tstrValuexy eq "0.4565,0.4097") { $tintValueCt=365; }
  elsif ($tstrValuexy eq "0.4626,0.4112") { $tintValueCt=375; }
  elsif ($tstrValuexy eq "0.4684,0.4122") { $tintValueCt=385; }
  elsif ($tstrValuexy eq "0.4741,0.4132") { $tintValueCt=395; }
  elsif ($tstrValuexy eq "0.4797,0.4139") { $tintValueCt=405; }
  elsif ($tstrValuexy eq "0.4852,0.4145") { $tintValueCt=415; }
  elsif ($tstrValuexy eq "0.4906,0.415") { $tintValueCt=425; }
  elsif ($tstrValuexy eq "0.4957,0.4151") { $tintValueCt=435; }
  elsif ($tstrValuexy eq "0.5008,0.4152") { $tintValueCt=445; }
  elsif ($tstrValuexy eq "0.5058,0.4151") { $tintValueCt=455; }
  elsif ($tstrValuexy eq "0.5106,0.4149") { $tintValueCt=465; }
  elsif ($tstrValuexy eq "0.5154,0.4146") { $tintValueCt=475; }
  elsif ($tstrValuexy eq "0.5199,0.4141") { $tintValueCt=485; }
  elsif ($tstrValuexy eq "0.5245,0.4136") { $tintValueCt=495; }
  elsif ($tstrValuexy eq "0.5267,0.4133") { $tintValueCt=500; }

  return($tintValueCt);
}
########################################################################################################################


########################################################################################################################
# Alle Geräte auflisten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $ptrarrResponse=$objGateway->listObjects();
#
# Übergabe: -
#
# Rückgabe: $ptrarrResponse = Zeiger auf Array=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub listObjects {
  my $lobjSelf=shift;  # Klasse-Name abfangen
  my $lstrResponse=""; # Antwort der Hue Bridge
  my $lptrResult="";   # Zeiger auf ein Array, Hash oder Sclar eines dekodierten JSON-Strings
  my @larrDevices=();  # Gefundene Geräte

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";

  # Liste der vorhandenen realen Geräte-ID's (ohne führendes "itfX") ermitteln
  $lptrResult=$lobjSelf->_getAllRealObjectIds();
  if (! defined($lptrResult)) { return; }
  
  # Alle ID's bearbeiten
  foreach my $tstrDeviceId (sort { $a cmp $b } @{$lptrResult}) {
  
    # Verzweigung nach Geräteart - Lampe/Steckdose
    if (($tstrDeviceId =~ /^phl/) || ($tstrDeviceId =~ /^php/))  {
      my $tstrPlainDeviceId=$tstrDeviceId; $tstrPlainDeviceId =~ s/^ph.//;
      # Alle Geräteinformationen auslesen
      $lstrResponse=$lobjSelf->_requestGateway(0,"/lights/".$tstrPlainDeviceId,"");
      push( @larrDevices,TSS::Philips::Hue::Light->new( gateway => $lobjSelf, deviceid => $tstrDeviceId, devicedata => $lstrResponse ) );
    }
    # Gruppe
    elsif ($tstrDeviceId =~ /^phg/)  {
      my $tstrPlainDeviceId=$tstrDeviceId; $tstrPlainDeviceId =~ s/^phg//;
      # Alle Geräteinformationen auslesen
      $lstrResponse=$lobjSelf->_requestGateway(0,"/groups/".$tstrPlainDeviceId,"");
      push( @larrDevices,TSS::Philips::Hue::Group->new( gateway => $lobjSelf, deviceid => $tstrDeviceId, devicedata => $lstrResponse ) );
    }
    # Unbekannt
    else {}
  
  }    

  # Erfolgreiche Rückmeldung
  return(\@larrDevices);
 }
########################################################################################################################


########################################################################################################################
# Geräteinformationen ausgeben
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->getDeviceInfo($strAddress);
#
# Übergabe: $strAddress = Geräte-ID (phl2)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub getDeviceInfo {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (phl2)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjDevices=();    # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }

  # Verzweigung nach Geräteart - Lampe/Steckdose
  if (( $lstrAddress =~ /^phl/) || ( $lstrAddress =~ /^php/)) { $lobjDevices=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Gruppe
  elsif ( $lstrAddress =~ /^phg/) { $lobjDevices=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="getDeviceInfo: Gerät '$lstrAddress' hat einen unbekannter Typ!"; return; }
 
  #Erfolgreiche Rückmeldung  
  return($lobjDevices);
}
########################################################################################################################


########################################################################################################################
# Alle Geräte schalten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->setPowerAll($intState);
#
# Übergabe: $intState    = Neuer Status (0=Aus, 1=Ein)
#
# Rückgabe: $strResponse = String=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setPowerAll {
  my $lobjSelf=shift;   # Klasse-Name abfangen
  my $lintState=shift;  # Neuer Status (0=Aus, 1=Ein)
  my $lprtarrLights=""; # Zeiger auf Array mit den Hue-Geräten

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";

  # Alle Geräte auflisten:
  $lprtarrLights=$lobjSelf->listObjects();
  if (! defined($lprtarrLights)) { return; }
  foreach my $tobjLight ( @{$lprtarrLights} ) {
    # Nur Lampen/Steckdosen
    if (($tobjLight->{"deviceid"} =~ /^phl.*$/) || ($tobjLight->{"deviceid"} =~ /^php.*$/)) {
      # Gerät schalten
      my $tstrResult=$tobjLight->setPower($lintState);
      if (! defined($tstrResult)) { return; }
    }
  }

  # Erfolgreiche Rückmeldung
  return("<datapoint deviceid='' status='".$lintState."' />");
}
########################################################################################################################


########################################################################################################################
# Alle Lampen schalten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->setPowerAllLights($intState);
#
# Übergabe: $intState    = Neuer Status (0=Aus, 1=Ein)
#
# Rückgabe: $strResponse = String=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setPowerAllLights {
  my $lobjSelf=shift;   # Klasse-Name abfangen
  my $lintState=shift;  # Neuer Status (0=Aus, 1=Ein)
  my $lprtarrLights=""; # Zeiger auf Array mit den Hue-Geräten

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";

  # Alle Geräte auflisten:
  $lprtarrLights=$lobjSelf->listObjects();
  if (! defined($lprtarrLights)) { return; }
  foreach my $tobjLight ( @{$lprtarrLights} ) {
    # Nur Lampen
    if ($tobjLight->{"deviceid"} =~ /^phl.*$/) {
      # Gerät schalten
      my $tstrResult=$tobjLight->setPower($lintState);
      if (! defined($tstrResult)) { return; }
    }
  }

  # Erfolgreiche Rückmeldung
  return("<datapoint deviceid='' status='".$lintState."' />");
}
########################################################################################################################


########################################################################################################################
# Alle Steckdosen schalten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->setPowerAllPlugs($intState);
#
# Übergabe: $intState    = Neuer Status (0=Aus, 1=Ein)
#
# Rückgabe: $strResponse = String=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setPowerAllPlugs {
  my $lobjSelf=shift;   # Klasse-Name abfangen
  my $lintState=shift;  # Neuer Status (0=Aus, 1=Ein)
  my $lprtarrLights=""; # Zeiger auf Array mit den Hue-Geräten

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";

  # Alle Geräte auflisten:
  $lprtarrLights=$lobjSelf->listObjects();
  if (! defined($lprtarrLights)) { return; }
  foreach my $tobjLight ( @{$lprtarrLights} ) {
    # Nur Lampen
    if ($tobjLight->{"deviceid"} =~ /^php.*$/) {
      # Gerät schalten
      my $tstrResult=$tobjLight->setPower($lintState);
      if (! defined($tstrResult)) { return; }
    }
  }

  # Erfolgreiche Rückmeldung
  return("<datapoint deviceid='' status='".$lintState."' />");
}
########################################################################################################################


########################################################################################################################
# Alle Gruppen schalten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objGateway->setPowerAllGroups($intState);
#
# Übergabe: $intState    = Neuer Status (0=Aus, 1=Ein)
#
# Rückgabe: $strResponse = string=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setPowerAllGroups {
  my $lobjSelf=shift;   # Klasse-Name abfangen
  my $lintState=shift;  # Neuer Status (0=Aus, 1=Ein)
  my $lprtarrGroups=""; # Zeiger auf Array mit den Hue-Gruppen

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";

  # Alle Geräte auflisten:
  $lprtarrGroups=$lobjSelf->listObjects();
  if (! defined($lprtarrGroups)) { return; }
  foreach my $tobjLight ( @{$lprtarrGroups} ) {
    # Nur Lampen
    if ($tobjLight->{"deviceid"} =~ /^phg.*$/) {
      # Gerät schalten
      my $tstrResult=$tobjLight->setPower($lintState);
      if (! defined($tstrResult)) { return; }
    }
  }

  # Erfolgreiche Rückmeldung
  return("<datapoint deviceid='' status='".$lintState."' />");
}
########################################################################################################################


########################################################################################################################
# Ein Gerät schalten
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->setPower($strAddress,$intState);
#
# Übergabe: $strAddress = Geräte-ID (phl2)
#           $intState   = Neuer Status (0=Aus, 1=Ein)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setPower {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (phl2)
  my $lintState=shift;   # Neuer Status (0=Aus, 1=Ein)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjLight=();      # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }
  
  # Ist das Gerät eine Lampe/Steckdose?
  if (($lstrAddress =~ /^phl/) || ($lstrAddress =~ /^php/)) { $lobjLight=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Ist das Gerät eine Gruppe?
  elsif ($lstrAddress =~ /^phg/) { $lobjLight=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="setPower: Gerät '$lstrAddress' ist keine Lampe und keine Gruppe!"; return; }

  # Das Gerät aus-/einschalten
  my $lstrResult=$lobjLight->setPower($lintState);
  if (! defined($lstrResult)) { return; }
  
  #Erfolgreiche Rückmeldung  
  return($lobjLight);
}
########################################################################################################################


########################################################################################################################
# Helligkeit eines Gerätes steuern
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->setBrightness($strAddress,$intValue);
#
# Übergabe: $strAddress = Geräte-ID (phl2)
#           $intValue   = Neue Helligkeit (0 - 254)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setBrightness {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (phl2)
  my $lintValue=shift;   # Neue Helligkeit (0 - 254)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjLight=();      # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }

  # Ist das Gerät eine Lampe?
  if ($lstrAddress =~ /^phl/) { $lobjLight=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Ist das Gerät eine Gruppe?
  elsif ($lstrAddress =~ /^phg/) { $lobjLight=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="setPower: Gerät '$lstrAddress' ist keine Lampe und keine Gruppe!"; return; }

  # Helligkeit des Gerätes ändern
  my $lstrResult=$lobjLight->setBrightness($lintValue);
  if (! defined($lstrResult)) { return; }
  
  #Erfolgreiche Rückmeldung  
  return($lobjLight);
}
########################################################################################################################


########################################################################################################################
# Farbtemperatur eines Gerätes steuern
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->setCT($strAddress,$intValue);
#
# Übergabe: $strAddress = Geräte-ID (phl2)
#           $intValue   = Neue Farbtemperatur (153 - 500)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setCT {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (phl2)
  my $lintValue=shift;   # Neue Farbtemperatur (153 - 500)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjLight=();      # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }
  
  # Ist das Gerät eine Lampe?
  if ($lstrAddress =~ /^phl/) { $lobjLight=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Ist das Gerät eine Gruppe?
  elsif ($lstrAddress =~ /^phg/) { $lobjLight=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="setPower: Gerät '$lstrAddress' ist keine Lampe und keine Gruppe!"; return; }

  # Kann an dem Gerät gar keine Farbtemeratur eingestellt werden?
  if ((!defined($lobjLight->{"colorx"})) && (!defined($lobjLight->{"ct"}))) { $lobjSelf->{"error"}="setCT: Das Gerät unterstützt keine Farbtemperatur!"; return; }

  # Farbtemperatur des Gerätes ändern
  my $lstrResult=$lobjLight->setCT($lintValue);
  if (! defined($lstrResult)) { return; }
  
  #Erfolgreiche Rückmeldung  
  return($lobjLight);
}
########################################################################################################################


########################################################################################################################
# Farbe eines Gerätes über xyY-Wert ändern
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->setXYY($strAddress,$strValue);
#
# Übergabe: $strAddress = Geräte-ID (itfl65544)
#           $strValue   = Neue Farbe (0-65535,0-65535,0-254)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setXYY {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (itfl65544)
  my $lstrValue=shift;   # Neue Neue Farbe (1-20)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjLight=();      # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }

  # Ist das Gerät eine Lampe?
  if ($lstrAddress =~ /^phl/) { $lobjLight=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Ist das Gerät eine Gruppe?
  elsif ($lstrAddress =~ /^phg/) { $lobjLight=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="setPower: Gerät '$lstrAddress' ist keine Lampe und keine Gruppe!"; return; }

  # Kann an dem Gerät gar keine Farbe eingestellt werden?
  if (!defined($lobjLight->{"colorx"})) { $lobjSelf->{"error"}="setXYY: Das Gerät unterstützt keine Farbeinstellung!"; return; }

  # Farbe des Gerätes ändern
  my $lstrResult=$lobjLight->setXYY($lstrValue);
  if (! defined($lstrResult)) { return; }
  
  #Erfolgreiche Rückmeldung  
  return($lobjLight);
}
########################################################################################################################


########################################################################################################################
# Farbe eines Gerätes über HSV-Wert ändern
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objDevice=$objGateway->setHsv($strAddress,$strValue);
#
# Übergabe: $strAddress = Geräte-ID (itfl65544)
#           $strValue   = Neue Farbe (0-65535,0-254,0-254)
#
# Rückgabe: $objDevice  = Hue Gerät=Erfolgreich, undef=Ein Fehler ist aufgetreten (Beschreibung in $objSelf->{"error"})
#
#-----------------------------------------------------------------------------------------------------------------------
sub setHsv {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lstrAddress=shift; # Geräte-ID (itfl65544)
  my $lstrValue=shift;   # Neue Neue Farbe (1-20)
  my $lstrJsonSring="";  # Geräteinformationen als JSON-Sting
  my $lobjLight=();      # Hue Gerät

  # Fehlertext bereinigen
  $lobjSelf->{"error"}="";
  
  # Überprüfen ob ein Hue Gerät vorhanden ist
  $lstrJsonSring=$lobjSelf->_checkObject($lstrAddress);
  if (! defined($lstrJsonSring)) { return; }

  # Ist das Gerät eine Lampe?
  if ($lstrAddress =~ /^phl/) { $lobjLight=TSS::Philips::Hue::Light->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Ist das Gerät eine Gruppe?
  elsif ($lstrAddress =~ /^phg/) { $lobjLight=TSS::Philips::Hue::Group->new(gateway => $lobjSelf, deviceid => $lstrAddress, devicedata => $lstrJsonSring); }
  # Unbekannt
  else { $lobjSelf->{"error"}="setPower: Gerät '$lstrAddress' ist keine Lampe und keine Gruppe!"; return; }

  # Kann an dem Gerät gar keine Farbe eingestellt werden?
  if (!defined($lobjLight->{"colorx"})) { $lobjSelf->{"error"}="setHsv: Das Gerät unterstützt keine Farbeinstellung!"; return; }

  # Farbe des Gerätes ändern
  my $lstrResult=$lobjLight->setHsv($lstrValue);
  if (! defined($lstrResult)) { return; }
  
  #Erfolgreiche Rückmeldung  
  return($lobjLight);
}
########################################################################################################################


########################################################################################################################
# Modul Aufräumen
#-----------------------------------------------------------------------------------------------------------------------
1;
########################################################################################################################
