########################################################################################################################
# Plug.pm
#-----------------------------------------------------------------------------------------------------------------------
#
# Steuerung von Ikea Tradfri Steckdosen
#
# Präfixe Device-ID: itfb Rollos (b=blind)
#                    itfg Gruppen (g=group)
#                    itfl Leuchten (l=light)
#                    itfm Bewegungsmelder (m=motion)
#                    itfp Steckdosen (p=plug)
#                    itfr Fernbedienungen (r=Remote)
#                    itfs Szenen (s=scene)
#
#
# Getestete Geräte:
# -
#
#
# Aufruf           : use TSS::Ikea::Tradfri::Plug;
#                    my $gobjDevice = TSS::Ikea::Tradfri::Plug->new( gateway => <Gateway>, devicedata => <Gerätedaten> );
#                    my $gobjDevice=$gobjGateway->getDeviceInfo("itfr12345"); # itfr12345=Geräte-ID-Fernbedienungen
#                    print $gobjDevice."\n";
#                      > <datapoint deviceid='itfp12345' name='Steckdose' devicetype='plug' online='1' status='1' batterylevel='87' />
#
#                    Version ausgeben:
#                    -----------------
#                    print "Version: ".$TSS::Ikea::Tradfri::Plug::VERSION."\n";
#                      > Version: v1.0.1
#
#                    Name des Gerätes ausgeben:
#                    --------------------------
#                    print $gobjDevice->name()."\n";
#                      > <datapoint deviceid='itfp12345' name='Steckdose' />
#
#                     Adresse des Gerätes ausgeben:
#                     -----------------------------
#                     print $gobjDevice->deviceid()."\n";
#                       > <datapoint deviceid='itfp12345' />
#
#                     Typ des Gerätes ausgeben:
#                     -------------------------
#                     print $gobjDevice->devicetype()."\n";
#                       > <datapoint deviceid='itfp12345' devicetype='plug' />
#
#                     Version des Gerätes ausgeben:
#                     -----------------------------
#                     print $gobjDevice->version()."\n";
#                       > <datapoint deviceid='itfp12345' version='2.2.008' />
#
#                     Erreichbarkeit des Gerätes ausgeben:
#                     ------------------------------------
#                     print $gobjDevice->online()."\n";
#                       > <datapoint deviceid='itfp12345' online='1' />
#
#                     Power-Status des Gerätes ausgeben:
#                     ----------------------------------
#                     print $gobjDevice->status()."\n";
#                       > <datapoint deviceid='itfp12345' status='1' />
#
#                     Batteriestand des Gerätes ausgeben:
#                     -----------------------------------
#                     print $gobjDevice->batterylevel()."\n";
#                       > <datapoint deviceid='itfp12345' batterylevel='87' />
#
#                     Gesamtstatus des Gerätes ausgeben:
#                     ----------------------------------
#                     print $gobjDevice->devicestate()."\n";
#                       > <datapoint deviceid='itfp12345' name='Steckdose' devicetype='plug' online='1' status='1' batterylevel='87' />
#
#
#                     Alle Geräteinformationen neu einlesen:
#                     --------------------------------------
#                     my $gintResult=$gobjDevice->readDeviceInfo();
#                     if (! defined($gintResult)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                     print $gobjDevice->devicestate()."\n";
#                       > <datapoint deviceid='itfp12345' name='Steckdose' devicetype='plug' online='1' status='1' batterylevel='87' />
#
#                     Das Gerät aus-/einschalten:
#                     ---------------------------
#                     my $gstrResult=$gobjDevice->setPower(x); # 0=aus, 1=ein
#                     if (! defined($gstrResult)) { print "Befehl nicht erfolgreich! Fehler:\"".$gobjGateway->{"error"}."\"\n"; exit(1); }
#                     else { print "$gstrResult\n"; }
#                       > <datapoint deviceid='itfp12345' status='1' />
#
#
# Attribute        : Fehlertext              = $lobjSelf->{"error"}
#                    Gateway                 = $lobjSelf->{"gateway"} (Übergeordnetes Objekt)
#                    Gerätedaten JSON-String = $lobjSelf->{"devicedata"}
#
#                    Gerätedaten Gerätetyp unabhängig:
#                    Gerätetyp               = $lobjSelf->{"devicetype"} (Ikea Gerätebezeichnung)
#                    Name                    = $lobjSelf->{"name"}
#                    Anmeldedatum            = $lobjSelf->{"created"} (Unix Timestamp)
#                    Geräte-ID               = $lobjSelf->{"deviceid"}
#                    Onlinestatus            = $lobjSelf->{"online"} (0=offline, 1=online)
#                    Letzter kontakt         = $lobjSelf->{"lastseen"} (Unix Timestamp)
#                    Update Status           = $lobjSelf->{"updatestate"} (Bedeutung unbekannt)
#                    Zugriffstyp             = $lobjSelf->{"accessorytype"} (0=Fernbedienung, 1=Slave Fernbedienung, 2=Lampe, 3=Steckdose, 4=Bewegungsmelder, 6=Repeater, 7=Rollo)
#
#                    Geräteeigenschaften Gerätetyp unabhänig
#                    Hersteller              = $lobjSelf->{"manufactor"}
#                    Seriennummer            = $lobjSelf->{"serialno"} (immer leer)
#                    Firmwareversion         = $lobjSelf->{"version"}
#                    Stromquelle             = $lobjSelf->{"powersource"} (0=Unbekannt, 1=Netzteil, 2=Externe Batterie, 3=Batterie, 4=PowerOverEthernet, 5=USB, 6=AC_Power, 7=Solar)
#                    Batteriestand           = $lobjSelf->{"batterylevel"} (optional in %)
#
#                    Gerätestatus Steckdosen
#                    Power-Status            = $lobjSelf->{"status"} (0=off, 1=on)
#                    Subdevice-ID            = $lobjSelf->{"subdeviceid"} (Integer)
#
# Methoden         : Name ausgeben                        = $gobjLight->name()
#                    Adresse ausgeben                     = $gobjLight->deviceid()
#                    Typ ausgeben                         = $gobjLight->devicetype()
#                    Version ausgeben                     = $gobjLight->version()
#                    Erreichbarkeit ausgeben              = $gobjLight->online()
#                    Power-Status ausgeben                = $gobjLight->status()
#                    Batteriestand ausgeben               = $gobjLight->batterylevel()
#                    Gesamtstatus ausgeben                = $gobjLight->devicestate()
#                    Geräteinformationen neu einlesen     = $gobjLight->readDeviceInfo()
#                    Aus-/einschalten                     = $gobjLight->setPower(<Status>) -> <Status> : 0=aus, 1=ein
#
# Gerätetypen      : "TRADFRI bulb E14 W op/ch 400lm"  = Lampe weiß fix, dimmbar
#                    "TRADFRI bulb E27 CWS opal 600lm" = Lampe farbe steuerbar, weiß steuerbar, dimmbar
#                    "TRADFRI bulb E14 CWS opal 600lm" = Lampe farbe steuerbar, weiß steuerbar, dimmbar
#                    "TRADFRI remote control"          = Fernbedinung rund 5 Tasten
#                    "TRADFRI on/off switch"           = Fernbedinung quadradisch 2 Tasten
#
# Zugriffstyp      : 0=Fernbedienung
#                    1=Slave Fernbedienung
#                    2=Lampe
#                    3=Steckdose
#                    4=Bewegungsmelder
#                    6=Repeater
#                    7=Rollo
#
# Stromquellen     : 0=Unbekannt
#                    1=Netzteil
#                    2=Externe Batterie
#                    3=Batterie
#                    4=PowerOverEthernet
#                    5=USB
#                    6=AC_Power
#                    7=Solar
#
# Präfixe Device-ID: itfb Rollos (b=blind)
#                    itfg Gruppen (g=group)
#                    itfl Leuchten (l=light)
#                    itfm Bewegungsmelder (m=motion)
#                    itfp Steckdosen (p=plug)
#                    itfr Fernbedienungen (r=Remote)
#                    itfs Szenen (s=scene)
#         
# Version          : 09.11.2019 v1.0.0 Initiale Version
#                    08.01.2020 v1.0.1 Allgemeine Überarbeitung
#                    05.02.2020 v1.0.2 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::Ikea::Tradfri::Plug;

# ========================
#  Definition der Pragmas
# ========================
use strict;
use warnings;
use JSON::Parse 'parse_json';
use TSS::Ikea::Tradfri::Common;

# ===============
#  Vererbung aus
# ===============
our @ISA = qw( TSS::Ikea::Tradfri::Common );

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

# ================================================
#  Überladung: Klassenattribute als Text ausgeben
# ================================================
use overload '""' => '_stringify';

########################################################################################################################
# Interne Variable
#-----------------------------------------------------------------------------------------------------------------------
########################################################################################################################


########################################################################################################################
# Gerätedaten aus JSON-String auswerten 
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $objSelf->_decodeDevicedata();
#
# Übergabe: -
#
# Rückgabe: -
#
#-----------------------------------------------------------------------------------------------------------------------
sub _decodeDevicedata {
  my $lobjSelf=shift;    # Klasse-Name abfangen
  my $lptrResult="";     # Zeiger auf ein Array, Hash oder Sclar eines dekodierten JSON-Strings
  my $lprtProperties=""; # Zeiger auf ein Array, Hash oder Sclar eines dekodierten JSON-Strings
  
  # Json-String dekodieren
  $lptrResult=parse_json($lobjSelf->{'devicedata'});
  
  # Unerwaretetes Ergebnis?
  if (ref($lptrResult) ne "HASH") { $lobjSelf->{"error"}="_decodeDevicedata: Unerwartetes Ergebnisformat (".ref($lptrResult).") !"; return; }

  # Gerätedaten Gerätetyp unabhängig
  #---------------------------------
  # Name
  if (defined($lptrResult->{"9001"})) { $lobjSelf->{"name"}=$lptrResult->{"9001"}; } else { $lobjSelf->{"name"}=""; }
  # Anmeldedatum (Unix Timestamp)
  if (defined($lptrResult->{"9002"})) { $lobjSelf->{"created"}=$lptrResult->{"9002"}; } else { $lobjSelf->{"created"}=""; }
  # Geräte-ID-Fernbedienungen
  if (defined($lptrResult->{"9003"})) { $lobjSelf->{"deviceid"}="itfp".$lptrResult->{"9003"}; } else { $lobjSelf->{"deviceid"}=""; }
  # Onlinestatus (0=offline, 1=online)
  if (defined($lptrResult->{"9019"})) { $lobjSelf->{"online"}=$lptrResult->{"9019"}; } else { $lobjSelf->{"online"}=""; }
  # Letzter kontakt (Unix Timestamp)
  if (defined($lptrResult->{"9020"})) { $lobjSelf->{"lastseen"}=$lptrResult->{"9020"}; } else { $lobjSelf->{"lastseen"}=""; }
  # Update Status (Bedeutung unbekannt)
  if (defined($lptrResult->{"9054"})) { $lobjSelf->{"updatestate"}=$lptrResult->{"9054"}; } else { $lobjSelf->{"updatestate"}=""; }
  # Zugriffstyp (0=Fernbedienung, 1=Slave Fernbedienung, 2=Lampe, 3=Steckdose, 4=Bewegungsmelder, 6=Repeater, 7=Rollo)
  if (defined($lptrResult->{"5750"})) { $lobjSelf->{"accessorytype"}=$lptrResult->{"5750"}; } else { $lobjSelf->{"accessorytype"}=""; }
  
  # Geräteeigenschaften übernehmen
  $lprtProperties=$lptrResult->{"3"};
    
  # Unerwaretetes Ergebnis?
  if (ref($lprtProperties) ne "HASH") { $lobjSelf->{"error"}="_decodeDevicedata: Unerwartetes Ergebnisformat (".ref($lprtProperties).") !"; return; }

  # Geräteeigenschaften Gerätetyp unabhänig
  #----------------------------------------
  # Hersteller
  if (defined($lprtProperties->{"0"})) { $lobjSelf->{"manufactor"}=$lprtProperties->{"0"}; } else { $lobjSelf->{"manufactor"}=""; }
  # Gerätebezeichnung
  $lobjSelf->{"devicetype"}="plug";
  # Seriennummer (immer leer)
  if (defined($lprtProperties->{"2"})) { $lobjSelf->{"serialno"}=$lprtProperties->{"2"}; } else { $lobjSelf->{"serialno"}=""; }
  # Firmwareversion
  if (defined($lprtProperties->{"3"})) { $lobjSelf->{"version"}=$lprtProperties->{"3"}; } else { $lobjSelf->{"version"}=""; }
  # Stromquelle (0=Unbekannt, 1=Netzteil, 2=Externe Batterie, 3=Batterie, 4=PowerOverEthernet, 5=USB, 6=AC_Power, 7=Solar)
  if (defined($lprtProperties->{"6"})) { $lobjSelf->{"powersource"}=$lprtProperties->{"6"}; } else { $lobjSelf->{"powersource"}=""; }
  # Batteriestand (optional in %)
  if (defined($lprtProperties->{"9"})) { $lobjSelf->{"batterylevel"}=$lprtProperties->{"9"}; }
  
  # Gerätestatus übernehmen
  $lprtProperties=$lptrResult->{"3312"}->[0];
    
  # Unerwaretetes Ergebnis?
  if (ref($lprtProperties) ne "HASH") { $lobjSelf->{"error"}="_decodeDevicedata: Unerwartetes Ergebnisformat (".ref($lprtProperties).") !"; return; }

  # Gerätestatus Steckdosen
  #------------------------
  # Power-Status (0=off, 1=on)
  if (defined($lprtProperties->{"5850"})) { $lobjSelf->{"status"}=$lprtProperties->{"5850"}; } else { $lobjSelf->{"status"}=0; }
  # Subdevice-ID (Integer)
  if (defined($lprtProperties->{"9003"})) { $lobjSelf->{"subdeviceid"}=$lprtProperties->{"9003"}; } else { $lobjSelf->{"subdeviceid"}=""; }

  # Erfolgreiche Rückmeldung
  return(0);
}
########################################################################################################################


########################################################################################################################
# Gesamtstatus des Gerätes ausgeben
#-----------------------------------------------------------------------------------------------------------------------
# Aufruf  : $strResponse=$objPlug->devicestate()
#
# Übergabe: -
#
# Rückgabe: $strResponse = Gesamtstatus des Gerätes
#
#-----------------------------------------------------------------------------------------------------------------------
sub devicestate {
  my $lobjSelf=shift; # Klasse-Name abfangen
  my $lstrReturn="";  # Rückgabestring
  # Rückgabestring einleiten
  $lstrReturn="<datapoint deviceid='".$lobjSelf->{"deviceid"}."'";
  # Name des Gerätes
  $lstrReturn=$lstrReturn." name='".$lobjSelf->{"name"}."'";
  # Typ des Gerätes
  $lstrReturn=$lstrReturn." devicetype='".$lobjSelf->{"devicetype"}."'";
  # Erreichbarkeit des Gerätes
  $lstrReturn=$lstrReturn." online='".$lobjSelf->{"online"}."'";
  # Power-Status des Gerätes
  $lstrReturn=$lstrReturn." status='".$lobjSelf->{"status"}."'";
  # Batteriestand des Gerätes
  if (defined($lobjSelf->{"batterylevel"})) { $lstrReturn=$lstrReturn." batterylevel='".$lobjSelf->{"batterylevel"}."'"; }
  # Rückgabestring abschließen
  $lstrReturn=$lstrReturn." />";
  return($lstrReturn);
}
########################################################################################################################


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