diff --git a/FHEM/82_LGTV_WebOS.pm b/FHEM/82_LGTV_WebOS.pm
new file mode 100644
index 0000000..d2603b5
--- /dev/null
+++ b/FHEM/82_LGTV_WebOS.pm
@@ -0,0 +1,401 @@
+###############################################################################
+#
+# Developed with VSCodium and richterger perl plugin.
+#
+# (c) 2017-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
+# All rights reserved
+#
+# Special thanks goes to comitters:
+# - Vitolinker / Commandref
+#
+#
+# This script 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 2 of the License, or
+# any later version.
+#
+# The GNU General Public License can be found at
+# http://www.gnu.org/copyleft/gpl.html.
+# A copy is found in the textfile GPL.txt and important notices to the license
+# from the author is found in LICENSE.txt distributed with these scripts.
+#
+# This script 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.
+#
+#
+# $Id:
+#
+###############################################################################
+package FHEM::LGTV_WebOS;
+
+use strict;
+use warnings;
+
+require FHEM::Devices::LGTV::LGTVWebOS;
+
+use FHEM::Meta;
+
+use GPUtils qw(GP_Import);
+
+#-- Run before package compilation
+BEGIN {
+ #-- Export to main context with different name
+ GP_Import(qw( readingFnAttributes));
+}
+
+sub ::LGTV_WebOS_Initialize { goto &Initialize }
+
+sub Initialize {
+ my $hash = shift;
+
+ # Provider
+ $hash->{ReadFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Read;
+ $hash->{WriteFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Write;
+
+ # Consumer
+ $hash->{SetFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Set;
+ $hash->{DefFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Define;
+ $hash->{UndefFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Undef;
+ $hash->{AttrFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Attr;
+ $hash->{AttrList} =
+ "disable:1 "
+ . "channelGuide:1 "
+ . "pingPresence:1 "
+ . "wakeOnLanMAC "
+ . "wakeOnLanBroadcast "
+ . "wakeupCmd "
+ . "keepAliveCheckTime "
+ . $readingFnAttributes;
+
+ return FHEM::Meta::InitMod( __FILE__, $hash );
+}
+
+1;
+
+__END__
+
+=pod
+=item device
+=item summary Controls LG SmartTVs run with WebOS Operating System
+=item summary_DE Steuert LG SmartTVs mit WebOS Betriebssystem
+
+=begin html
+
+
+
LGTV_WebOS
+
+
+ This module controls SmartTVs from LG based on WebOS as operation system via network. It offers to swtich the TV channel, start and switch applications, send remote control commands, as well as to query the actual status.
+
+ Definition define <name> LGTV_WebOS <IP-Address>
+
+
+
+ When an LGTV_WebOS-Module is defined, an internal routine is triggered which queries the TV's status every 15s and triggers respective Notify / FileLog Event definitions.
+
+
+
+
+
+
+ define TV LGTV_WebOS 192.168.0.10
+
+
+ Set-Commands set <Name> <Command> [<Parameter>]
+
+
+ The following commands are supported in the actual version:
+
+
+
+
+
+ - connect - Connects to the TV at the defined address. When triggered the first time, a pairing is conducted
+ - pairing - Sends a pairing request to the TV which needs to be confirmed by the user with remote control
+ - screenMsg <Text> - Displays a message for 3-5s on the TV in the top right corner of the screen
+ - mute on, off - Turns volume to mute. Depending on the audio connection, this needs to be set on the AV Receiver (see volume)
+ - volume 0-100, Slider - Sets the volume. Depending on the audio connection, this needs to be set on the AV Receiver (see mute)
+ - volumeUp - Increases the volume by 1
+ - volumeDown - Decreases the volume by 1
+ - channelUp - Switches the channel to the next one
+ - channelDown - Switches the channel to the previous one
+ - getServiceList - Queries the running services on WebOS (in beta phase)
+ - on - Turns the TV on, depending on type of device. Only working when LAN or Wifi connection remains active during off state.
+ - off - Turns the TV off, when an active connection is established
+ - launchApp <Application> - Activates an application out of the following list (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV)
Note: TV is an application in LG's terms and not an input connection
+ - 3D on,off - 3D Mode is turned on and off. Depending on type of TV there might be different modes (e.g. Side-by-Side, Top-Bottom)
+ - stop - Stop command (depending on application)
+ - play - Play command (depending on application)
+ - pause - Pause command (depending on application)
+ - rewind - Rewind command (depending on application)
+ - fastForward - Fast Forward command (depending on application)
+ - clearInputList - Clears list of Inputs
+ - input - Selects the input connection (depending on the actual TV type and connected devices)
e.g.: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)
+
+
+
+ Get-Command get <Name> <Readingname>
+
+
+ Currently, GET reads back the values of the current readings. Please see below for a list of Readings / Generated Events.
+
+
+
Attributes
+
+
+ - disable
+ Optional attribute to deactivate the recurring status updates. Manual trigger of update is alsways possible.
+ Valid Values: 0 => recurring status updates, 1 => no recurring status updates.
+
+
+
+
+ - channelGuide
+ Optional attribute to deactivate the recurring TV Guide update. Depending on TV and FHEM host, this causes significant network traffic and / or CPU load
+ Valid Values: 0 => no recurring TV Guide updates, 1 => recurring TV Guide updates.
+
+
+
+
+ - pingPresence
+ current state of ping presence from TV. create a reading presence with values absent or present.
+
+
+
+
+ - keepAliveCheckTime
+ value in seconds - keepAliveCheck is check read data input from tcp socket and prevented FHEM freeze.
+
+
+
+
+ - wakeOnLanMAC
+ Network MAC Address of the LG TV Networkdevice.
+
+
+
+
+ - wakeOnLanBroadcast
+ Broadcast Address of the Network - wakeOnLanBroadcast <network>.255
+
+
+
+
+ - wakeupCmd
+ Set a command to be executed when turning on an absent device. Can be an FHEM command or Perl command in {}.
+
+
+
+
+=end html
+
+=begin html_DE
+
+
+LGTV_WebOS
+
+
+ Dieses Modul steuert SmartTV's des Herstellers LG mit dem Betriebssystem WebOS über die Netzwerkschnittstelle. Es bietet die Möglichkeit den aktuellen TV Kanal zu steuern, sowie Apps zu starten, Fernbedienungsbefehle zu senden, sowie den aktuellen Status abzufragen.
+
+
Definition define <name> LGTV_WebOS <IP-Addresse>
+
+
+ Bei der Definition eines LGTV_WebOS-Moduls wird eine interne Routine in Gang gesetzt, welche regelmäßig alle 15s den Status des TV abfragt und entsprechende Notify-/FileLog-Definitionen triggert.
+
+
+
+
+ Beispiel: define TV LGTV_WebOS 192.168.0.10
+
+
+ Set-Kommandos set <Name> <Kommando> [<Parameter>]
+
+
+ Aktuell werden folgende Kommandos unterstützt.
+
+
+
+
+
+
+ - connect - Verbindet sich zum Fernseher unter der IP wie definiert, führt beim ersten mal automatisch ein pairing durch
+ - pairing - Berechtigungsanfrage an den Fernseher, hier muss die Anfrage mit der Fernbedienung bestätigt werden
+ - screenMsg <Text> - zeigt für ca 3-5s eine Nachricht auf dem Fernseher oben rechts an
+ - mute on, off - Schaltet den Fernseher Stumm, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe Volume)
+ - volume 0-100, Schieberegler - Setzt die Lautstärke des Fernsehers, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe mute)
+ - volumeUp - Erhöht die Lautstärke um den Wert 1
+ - volumeDown - Verringert die Lautstärke um den Wert 1
+ - channelUp - Schaltet auf den nächsten Kanal um
+ - channelDown - Schaltet auf den vorherigen Kanal um
+ - getServiceList - Fragrt die Laufenden Dienste des Fernsehers an (derzeit noch in Beta-Phase)
+ - on - Schaltet den Fernseher ein, wenn WLAN oder LAN ebenfalls im Aus-Zustand aktiv ist (siehe Bedienungsanleitung da Typabhängig)
+ - off - Schaltet den Fernseher aus, wenn eine Connection aktiv ist
+ - launchApp <Anwendung> - Aktiviert eine Anwendung aus der Liste (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV)
Achtung: TV ist hier eine Anwendung, und kein Geräteeingang
+ - 3D on,off - 3D Modus kann hier ein- und ausgeschaltet werden, je nach Fernseher können mehrere 3D Modi unterstützt werden (z.B. Side-by-Side, Top-Bottom)
+ - stop - Stop-Befehl (anwendungsabhängig)
+ - play - Play-Befehl (anwendungsabhängig)
+ - pause - Pause-Befehl (anwendungsabhängig)
+ - rewind - Zurückspulen-Befehl (anwendungsabhängig)
+ - fastForward - Schneller-Vorlauf-Befehl (anwendungsabhängig)
+ - clearInputList - Löscht die Liste der Geräteeingänge
+ - input - Wählt den Geräteeingang aus (Abhängig von Typ und angeschossenen Geräten)
Beispiele: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)
+
+
+
+ Get-Kommandos get <Name> <Readingname>
+
+
+ Aktuell stehen via GET lediglich die Werte der Readings zur Verfügung. Eine genaue Auflistung aller möglichen Readings folgen unter "Generierte Readings/Events".
+
+
+
Attribute
+
+
+
+ - disable
+ Optionales Attribut zur Deaktivierung des zyklischen Status-Updates. Ein manuelles Update via statusRequest-Befehl ist dennoch möglich.
+
+
+
+
+
+ Mögliche Werte: 0 => zyklische Status-Updates, 1 => keine zyklischen Status-Updates.
+
+
+
+
+
+ - channelGuide
+ Optionales Attribut zur Deaktivierung der zyklischen Updates des TV-Guides, dieses beansprucht je nach Hardware einigen Netzwerkverkehr und Prozessorlast
+
+
+
+
+
+ Mögliche Werte: 0 => keine zyklischen TV-Guide-Updates, 1 => zyklische TV-Guide-Updates
+
+
+
+
+
+ - wakeOnLanMAC
+ MAC Addresse der Netzwerkkarte vom LG TV
+
+
+
+
+
+
+ - wakeOnLanBroadcast
+ Broadcast Netzwerkadresse - wakeOnLanBroadcast <netzwerk>.255
+
+
+
+
+
+
+ - pingPresence
+ Mögliche Werte: 0 => presence via ping deaktivert, 1 => presence via ping aktiviert
+
+
+
+
+
+
+ - keepAliveCheckTime
+ Wert in Sekunden - keepAliveCheckTime
+ kontrolliert in einer bestimmten Zeit ob noch Daten über die TCP Schnittstelle kommen und verhindert somit FHEM Freezes
+
+
+
+
+
+
+ - wakeupCmd
+ Befehl zum Einschalten des LG TV. Möglich ist ein FHEM Befehl oder Perl in {}.
+
+
+
+
Generierte Readings/Events:
+
+
+ - 3D - Status des 3D-Wiedergabemodus ("on" => 3D Wiedergabemodus aktiv, "off" => 3D Wiedergabemodus nicht aktiv)
+ - 3DMode - Anzeigemodus (2d, 2dto3d, side_side_half, line_interleave_half, column_interleave, check_board)
+ - channel - Die Nummer des aktuellen TV-Kanals
+ - channelName - Der Name des aktuellen TV-Kanals
+ - channelMedia - Senderinformation
+ - channelCurrentEndTime - Ende der laufenden Sendung (Beta)
+ - channelCurrentStartTime - Start der laufenden Sendung (Beta)
+ - channelCurrentTitle - Der Name der laufenden Sendung (Beta)
+ - channelNextEndTime - Ende der nächsten Sendung (Beta)
+ - channelNextStartTime - Start der nächsten Sendung (Beta)
+ - channelNextTitle - Der Name der nächsten Sendung (Beta)
+ - extInput_<Geräteeingang> - Status der Eingangsquelle (connect_true, connect_false)
+ - input - Derzeit aktiver Geräteeingang
+ - lastResponse - Status der letzten Anfrage (ok, error <Fehlertext>)
+ - launchApp <Anwendung> - Gegenwärtige aktive Anwendung
+ - lgKey - Der Client-Key, der für die Verbindung verwendet wird
+ - mute on,off - Der aktuelle Stumm-Status ("on" => Stumm, "off" => Laut)
+ - pairing paired, unpaired - Der Status des Pairing
+ - presence absent, present - Der aktuelle Power-Status ("present" => eingeschaltet, "absent" => ausgeschaltet)
+ - state on, off - Status des Fernsehers (ähnlich presence)
+ - volume - Der aktuelle Lautstärkepegel -1, 0-100 (-1 invalider Wert)
+
+
+
+=end html_DE
+
+=for :application/json;q=META.json 82_LGTV_WebOS.pm
+{
+ "abstract": "Module for Controls LG SmartTVs run with WebOS Operating System",
+ "x_lang": {
+ "de": {
+ "abstract": "Modul zur Steuerung von LG SmartTVs mit WebOS Betriebssystem"
+ }
+ },
+ "keywords": [
+ "fhem-mod-device",
+ "fhem-core",
+ "Multimedia",
+ "TV",
+ "LG"
+ ],
+ "release_status": "stable",
+ "license": "GPL_2",
+ "version": "v3.6.1",
+ "author": [
+ "Marko Oldenburg "
+ ],
+ "x_fhem_maintainer": [
+ "CoolTux"
+ ],
+ "x_fhem_maintainer_github": [
+ "LeonGaultier"
+ ],
+ "prereqs": {
+ "runtime": {
+ "requires": {
+ "FHEM": 5.00918799,
+ "perl": 5.016,
+ "Meta": 1,
+ "JSON": 1,
+ "Date::Parse": 0
+ },
+ "recommends": {
+ "JSON": 0
+ },
+ "suggests": {
+ "Cpanel::JSON::XS": 0,
+ "JSON::XS": 0
+ }
+ }
+ }
+}
+=end :application/json;q=META.json
+
+=cut
diff --git a/controls_LGTV_WebOS.txt b/controls_LGTV_WebOS.txt
new file mode 100644
index 0000000..e0a8534
--- /dev/null
+++ b/controls_LGTV_WebOS.txt
@@ -0,0 +1,2 @@
+UPD 2022-02-08_07:16:43 18966 FHEM/82_LGTV_WebOS.pm
+UPD 2022-02-08_07:16:48 54278 lib/FHEM/Devices/LGTV/LGTVWebOS.pm
diff --git a/hooks/pre-commit b/hooks/pre-commit
new file mode 100755
index 0000000..c009d1c
--- /dev/null
+++ b/hooks/pre-commit
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+use File::Basename;
+use POSIX qw(strftime);
+use strict;
+
+my @filenames =
+ ( 'FHEM/82_LGTV_WebOS.pm', 'lib/FHEM/Devices/LGTV/LGTVWebOS.pm' );
+
+my $controlsfile = 'controls_LGTV_WebOS.txt';
+
+open( FH, ">$controlsfile" ) || return ("Can't open $controlsfile: $!");
+
+for my $filename (@filenames) {
+ my @statOutput = stat($filename);
+
+ if ( scalar @statOutput != 13 ) {
+ printf 'error: stat has unexpected return value for '
+ . $filename . "\n";
+ next;
+ }
+
+ my $mtime = $statOutput[9];
+ my $date = POSIX::strftime( "%Y-%m-%d", localtime($mtime) );
+ my $time = POSIX::strftime( "%H:%M:%S", localtime($mtime) );
+ my $filetime = $date . "_" . $time;
+
+ my $filesize = $statOutput[7];
+
+ printf FH 'UPD ' . $filetime . ' ' . $filesize . ' ' . $filename . "\n";
+}
+
+close(FH);
+
+system("git add $controlsfile");
+
+print 'Create controls File succesfully' . "\n";
+
+exit 0;
diff --git a/82_LGTV_WebOS.pm b/lib/FHEM/Devices/LGTV/LGTVWebOS.pm
similarity index 51%
rename from 82_LGTV_WebOS.pm
rename to lib/FHEM/Devices/LGTV/LGTVWebOS.pm
index 372275e..5599248 100644
--- a/82_LGTV_WebOS.pm
+++ b/lib/FHEM/Devices/LGTV/LGTVWebOS.pm
@@ -25,30 +25,37 @@
# GNU General Public License for more details.
#
#
-# $Id: 82_LGTV_WebOS.pm 25389 2021-12-30 15:48:41Z CoolTux $
+# $Id:
#
###############################################################################
-
-#################################
-######### Wichtige Hinweise und Links #################
-#
-## Das JSON Modul immer in einem eval aufrufen
-# $data = eval{decode_json($data)};
-#
-##
-##
-##
-#
-
-################################
-
-package main;
+package FHEM::Devices::LGTV::LGTVWebOS;
use strict;
use warnings;
use experimental qw /switch/;
+## try / catch
+use Try::Tiny;
+
+# use Carp;
+use autodie qw /:io/;
+##
+
use FHEM::Meta;
+use GPUtils qw(GP_Import);
+
+#-- Run before package compilation
+BEGIN {
+ #-- Export to main context with different name
+ GP_Import(
+ qw(
+ modules
+ init_done
+ selectlist
+ defs
+ )
+ );
+}
my $missingModul = "";
@@ -194,33 +201,9 @@ my %openApps = (
my %openAppsPackageName = reverse %openApps;
-sub LGTV_WebOS_Initialize {
- my ($hash) = @_;
-
- # Provider
- $hash->{ReadFn} = "LGTV_WebOS_Read";
- $hash->{WriteFn} = "LGTV_WebOS_Write";
-
- # Consumer
- $hash->{SetFn} = "LGTV_WebOS_Set";
- $hash->{DefFn} = "LGTV_WebOS_Define";
- $hash->{UndefFn} = "LGTV_WebOS_Undef";
- $hash->{AttrFn} = "LGTV_WebOS_Attr";
- $hash->{AttrList} =
- "disable:1 "
- . "channelGuide:1 "
- . "pingPresence:1 "
- . "wakeOnLanMAC "
- . "wakeOnLanBroadcast "
- . "wakeupCmd "
- . "keepAliveCheckTime "
- . $readingFnAttributes;
-
- return FHEM::Meta::InitMod( __FILE__, $hash );
-}
-
-sub LGTV_WebOS_Define {
- my ( $hash, $def ) = @_;
+sub Define {
+ my $hash = shift;
+ my $def = shift;
my $version;
return $@ unless ( FHEM::Meta::SetInternals($hash) );
@@ -245,44 +228,50 @@ sub LGTV_WebOS_Define {
$hash->{helper}{device}{registered} = 0;
$hash->{helper}{device}{runsetcmd} = 0;
- Log3( $name, 3, "LGTV_WebOS ($name) - defined with host $host" );
+ ::Log3( $name, 3, "LGTV_WebOS ($name) - defined with host $host" );
- $attr{$name}{devStateIcon} = 'on:10px-kreis-gruen:off off:10px-kreis-rot:on'
- if ( !defined( $attr{$name}{devStateIcon} ) );
- $attr{$name}{room} = 'LGTV' if ( !defined( $attr{$name}{room} ) );
- CommandDeleteReading( undef, $name . ' presence' )
- if ( AttrVal( $name, 'pingPresence', 0 ) == 0 );
+ ::CommandAttr( undef,
+ $name . ' devStateIcon on:10px-kreis-gruen:off off:10px-kreis-rot:on' )
+ if ( ::AttrVal( $name, 'devStateIcon', 'none' ) eq 'none' );
+ ::CommandAttr( undef, $name . ' room LGTV' )
+ if ( ::AttrVal( $name, 'room', 'none' ) eq 'none' );
+
+ ::CommandDeleteReading( undef, $name . ' presence' )
+ if ( ::AttrVal( $name, 'pingPresence', 0 ) == 0 );
$modules{LGTV_WebOS}{defptr}{ $hash->{HOST} } = $hash;
+ ::readingsSingleUpdate( $hash, 'state', 'Initialized', 1 );
+
if ($init_done) {
- LGTV_WebOS_TimerStatusRequest($hash);
+ TimerStatusRequest($hash);
}
else {
- InternalTimer( gettimeofday() + 15,
- "LGTV_WebOS_TimerStatusRequest", $hash );
+ ::InternalTimer( ::gettimeofday() + 15,
+ \&FHEM::Devices::LGTV::LGTVWebOS::TimerStatusRequest, $hash );
}
$hash->{helper}->{lastResponse} =
- int( gettimeofday() ); # Check Socket KeepAlive
+ int( ::gettimeofday() ); # Check Socket KeepAlive
return;
}
-sub LGTV_WebOS_Undef {
- my ( $hash, $arg ) = @_;
+sub Undef {
+ my $hash = shift;
+ my $arg = shift;
my $host = $hash->{HOST};
my $name = $hash->{NAME};
- RemoveInternalTimer($hash);
+ ::RemoveInternalTimer($hash);
delete $modules{LGTV_WebOS}{defptr}{ $hash->{HOST} };
- Log3( $name, 3, "LGTV_WebOS ($name) - device $name deleted" );
+ ::Log3( $name, 3, "LGTV_WebOS ($name) - device $name deleted" );
return;
}
-sub LGTV_WebOS_Attr {
+sub Attr {
my ( $cmd, $name, $attrName, $attrVal ) = @_;
my $hash = $defs{$name};
@@ -290,29 +279,29 @@ sub LGTV_WebOS_Attr {
if ( $attrName eq "disable" ) {
if ( $cmd eq "set" && $attrVal eq "1" ) {
- RemoveInternalTimer($hash);
- readingsSingleUpdate( $hash, "state", "disabled", 1 );
+ ::RemoveInternalTimer($hash);
+ ::readingsSingleUpdate( $hash, "state", "disabled", 1 );
$hash->{PARTIAL} = '';
- Log3( $name, 3, "LGTV_WebOS ($name) - disabled" );
+ ::Log3( $name, 3, "LGTV_WebOS ($name) - disabled" );
}
elsif ( $cmd eq "del" ) {
- readingsSingleUpdate( $hash, "state", "active", 1 );
- Log3( $name, 3, "LGTV_WebOS ($name) - enabled" );
- LGTV_WebOS_TimerStatusRequest($hash);
+ ::readingsSingleUpdate( $hash, "state", "active", 1 );
+ ::Log3( $name, 3, "LGTV_WebOS ($name) - enabled" );
+ TimerStatusRequest($hash);
}
}
if ( $attrName eq "disabledForIntervals" ) {
if ( $cmd eq "set" ) {
- Log3( $name, 3,
+ ::Log3( $name, 3,
"LGTV_WebOS ($name) - enable disabledForIntervals" );
- readingsSingleUpdate( $hash, "state", "Unknown", 1 );
+ ::readingsSingleUpdate( $hash, "state", "Unknown", 1 );
}
elsif ( $cmd eq "del" ) {
- readingsSingleUpdate( $hash, "state", "active", 1 );
- Log3( $name, 3,
+ ::readingsSingleUpdate( $hash, "state", "active", 1 );
+ ::Log3( $name, 3,
"LGTV_WebOS ($name) - delete disabledForIntervals" );
}
}
@@ -320,93 +309,94 @@ sub LGTV_WebOS_Attr {
return;
}
-sub LGTV_WebOS_TimerStatusRequest {
+sub TimerStatusRequest {
my $hash = shift;
my $name = $hash->{NAME};
- RemoveInternalTimer( $hash, 'LGTV_WebOS_TimerStatusRequest' );
+ ::RemoveInternalTimer( $hash, \&TimerStatusRequest );
- readingsBeginUpdate($hash);
+ ::readingsBeginUpdate($hash);
- if ( !IsDisabled($name)
+ if ( !::IsDisabled($name)
&& $hash->{CD}
&& $hash->{helper}{device}{registered} == 1 )
{
- Log3( $name, 4, "LGTV_WebOS ($name) - run get functions" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - run get functions" );
- LGTV_WebOS_Presence($hash)
- if ( AttrVal( $name, 'pingPresence', 0 ) == 1 );
+ Presence($hash)
+ if ( ::AttrVal( $name, 'pingPresence', 0 ) == 1 );
if ( $hash->{helper}{device}{channelguide}{counter} > 2
- && AttrVal( $name, 'channelGuide', 0 ) == 1
- && ReadingsVal( $name, 'launchApp', 'TV' ) eq 'TV' )
+ && ::AttrVal( $name, 'channelGuide', 0 ) == 1
+ && ::ReadingsVal( $name, 'launchApp', 'TV' ) eq 'TV' )
{
- LGTV_WebOS_GetChannelProgramInfo($hash);
+ GetChannelProgramInfo($hash);
$hash->{helper}{device}{channelguide}{counter} = 0;
}
else {
- LGTV_WebOS_GetAudioStatus($hash);
- InternalTimer( gettimeofday() + 2,
- 'LGTV_WebOS_GetCurrentChannel', $hash )
- if ( ReadingsVal( $name, 'launchApp', 'TV' ) eq 'TV' );
- InternalTimer( gettimeofday() + 4,
- 'LGTV_WebOS_GetForgroundAppInfo', $hash );
- InternalTimer( gettimeofday() + 6, 'LGTV_WebOS_Get3DStatus',
- $hash );
- InternalTimer( gettimeofday() + 8,
- 'LGTV_WebOS_GetExternalInputList', $hash );
+ GetAudioStatus($hash);
+ ::InternalTimer( ::gettimeofday() + 2,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetCurrentChannel, $hash )
+ if ( ::ReadingsVal( $name, 'launchApp', 'TV' ) eq 'TV' );
+ ::InternalTimer( ::gettimeofday() + 4,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetForgroundAppInfo, $hash );
+ ::InternalTimer( ::gettimeofday() + 6,
+ \&FHEM::Devices::LGTV::LGTVWebOS::Get3DStatus, $hash );
+ ::InternalTimer( ::gettimeofday() + 8,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetExternalInputList, $hash );
}
}
- elsif ( IsDisabled($name) ) {
+ elsif ( ::IsDisabled($name) ) {
- LGTV_WebOS_Close($hash);
- LGTV_WebOS_Presence($hash)
- if ( AttrVal( $name, 'pingPresence', 0 ) == 1 );
+ Close($hash);
+ Presence($hash)
+ if ( ::AttrVal( $name, 'pingPresence', 0 ) == 1 );
$hash->{helper}{device}{runsetcmd} = 0;
- readingsBulkUpdateIfChanged( $hash, 'state', 'disabled' );
+ ::readingsBulkUpdateIfChanged( $hash, 'state', 'disabled' );
}
else {
+ ::readingsSingleUpdate( $hash, 'state', 'off', 1 )
+ if ( ::ReadingsVal( $name, 'state', 'off' ) ne 'off' );
- LGTV_WebOS_Presence($hash)
- if ( AttrVal( $name, 'pingPresence', 0 ) == 1 );
+ Presence($hash)
+ if ( ::AttrVal( $name, 'pingPresence', 0 ) == 1 );
- readingsBulkUpdateIfChanged( $hash, 'channel', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelName', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelMedia', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentStartTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentEndTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextTitle', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextStartTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextEndTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channel', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelName', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelMedia', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentStartTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentEndTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextTitle', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextStartTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextEndTime', '-' );
$hash->{helper}{device}{runsetcmd} = 0;
}
- readingsEndUpdate( $hash, 1 );
+ ::readingsEndUpdate( $hash, 1 );
- LGTV_WebOS_Open($hash) if ( !IsDisabled($name) && !$hash->{CD} );
+ Open($hash) if ( !::IsDisabled($name) && !$hash->{CD} );
$hash->{helper}{device}{channelguide}{counter} =
$hash->{helper}{device}{channelguide}{counter} + 1;
- InternalTimer( gettimeofday() + 10, "LGTV_WebOS_TimerStatusRequest",
- $hash );
+ ::InternalTimer( ::gettimeofday() + 10,
+ \&FHEM::Devices::LGTV::LGTVWebOS::TimerStatusRequest, $hash );
- LGTV_WebOS_SocketKeepAlive($hash)
- if ( AttrVal( $name, 'keepAliveCheckTime', 0 ) > 0 )
+ SocketKeepAlive($hash)
+ if ( ::AttrVal( $name, 'keepAliveCheckTime', 0 ) > 0 )
; # Check Socket KeepAlive
return;
}
-sub LGTV_WebOS_Set
-{ ## no critic (Subroutine "LGTV_WebOS_Set" with high complexity score)
+sub Set { ## no critic (Subroutine "Set" with high complexity score)
my ( $hash, $name, $cmd, @args ) = @_;
my ( $arg, @params ) = @args;
@@ -417,7 +407,7 @@ sub LGTV_WebOS_Set
when ('connect') {
return "usage: connect" if ( @args != 0 );
- LGTV_WebOS_Open($hash);
+ Open($hash);
return;
@@ -434,7 +424,7 @@ sub LGTV_WebOS_Set
when ('pairing') {
return "usage: pairing" if ( @args != 0 );
- LGTV_WebOS_Pairing($hash);
+ Pairing($hash);
return;
@@ -453,22 +443,22 @@ sub LGTV_WebOS_Set
$uri = $lgCommands{powerOff};
}
when ('on') {
- if ( AttrVal( $name, 'wakeOnLanMAC', 'none' ) ne 'none' ) {
- LGTV_WebOS_WakeUp_Udp(
+ if ( ::AttrVal( $name, 'wakeOnLanMAC', 'none' ) ne 'none' ) {
+ WakeUp_Udp(
$hash,
- AttrVal( $name, 'wakeOnLanMAC', 0 ),
- AttrVal( $name, 'wakeOnLanBroadcast', '255.255.255.255' )
+ ::AttrVal( $name, 'wakeOnLanMAC', 0 ),
+ ::AttrVal( $name, 'wakeOnLanBroadcast', '255.255.255.255' )
);
return;
}
- elsif ( AttrVal( $name, 'wakeupCmd', 'none' ) ne 'none' ) {
- my $wakeupCmd = AttrVal( $name, 'wakeupCmd', 'none' );
+ elsif ( ::AttrVal( $name, 'wakeupCmd', 'none' ) ne 'none' ) {
+ my $wakeupCmd = ::AttrVal( $name, 'wakeupCmd', 'none' );
if ( $wakeupCmd =~ s/^[ \t]*\{|\}[ \t]*$//xg ) {
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS executing wake-up command (Perl): $wakeupCmd"
);
eval { $wakeupCmd } or do {
- Log3( $name, 2,
+ ::Log3( $name, 2,
"LGTV_WebOS executing wake-up command (Perl): $wakeupCmd failed"
);
return;
@@ -476,10 +466,10 @@ sub LGTV_WebOS_Set
return;
}
else {
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS executing wake-up command (fhem): $wakeupCmd"
);
- fhem $wakeupCmd;
+ ::fhem $wakeupCmd;
return;
}
}
@@ -636,7 +626,7 @@ sub LGTV_WebOS_Set
## no critic (Expression form of map. See page 169 of PBP)
=> map qq{$_} => keys %{ $hash->{helper}{device}{inputs} }
)
- if ( defined( $hash->{helper}{device}{inputs} )
+ if ( exists( $hash->{helper}{device}{inputs} )
&& ref( $hash->{helper}{device}{inputs} ) eq "HASH" );
return "Unknown argument $cmd, choose one of $list";
@@ -644,17 +634,17 @@ sub LGTV_WebOS_Set
}
$hash->{helper}{device}{runsetcmd} = $hash->{helper}{device}{runsetcmd} + 1;
- return LGTV_WebOS_CreateSendCommand( $hash, $uri, \%payload );
+ return CreateSendCommand( $hash, $uri, \%payload );
}
-sub LGTV_WebOS_Open {
+sub Open {
my $hash = shift;
my $name = $hash->{NAME};
my $host = $hash->{HOST};
my $port = 3000;
my $timeout = 0.1;
- Log3( $name, 4, "LGTV_WebOS ($name) - Baue Socket Verbindung auf" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Baue Socket Verbindung auf" );
my $socket = IO::Socket::INET->new(
PeerHost => $host,
@@ -663,7 +653,7 @@ sub LGTV_WebOS_Open {
KeepAlive => 1,
Timeout => $timeout
)
- or return Log3( $name, 4,
+ or return ::Log3( $name, 4,
"LGTV_WebOS ($name) Couldn't connect to $host:$port" ); # open Socket
$hash->{FD} = $socket->fileno();
@@ -671,17 +661,17 @@ sub LGTV_WebOS_Open {
$selectlist{$name} = $hash;
$hash->{helper}->{lastResponse} =
- int( gettimeofday() ); # Check Socket KeepAlive
+ int( ::gettimeofday() ); # Check Socket KeepAlive
- Log3( $name, 4, "LGTV_WebOS ($name) - Socket Connected" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Socket Connected" );
- LGTV_WebOS_Handshake($hash);
- Log3( $name, 4, "LGTV_WebOS ($name) - start Handshake" );
+ Handshake($hash);
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - start Handshake" );
return;
}
-sub LGTV_WebOS_Close {
+sub Close {
my $hash = shift;
my $name = $hash->{NAME};
@@ -695,38 +685,39 @@ sub LGTV_WebOS_Close {
delete( $selectlist{$name} );
delete( $hash->{FD} );
- readingsSingleUpdate( $hash, 'state', 'off', 1 );
+ ::readingsSingleUpdate( $hash, 'state', 'off', 1 );
- Log3( $name, 4, "LGTV_WebOS ($name) - Socket Disconnected" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Socket Disconnected" );
return;
}
-sub LGTV_WebOS_Write {
+sub Write {
+ my $hash = shift;
+ my $string = shift;
- my ( $hash, $string ) = @_;
my $name = $hash->{NAME};
- Log3( $name, 4, "LGTV_WebOS ($name) - WriteFn called" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - WriteFn called" );
- return Log3( $name, 4, "LGTV_WebOS ($name) - socket not connected" )
+ return ::Log3( $name, 4, "LGTV_WebOS ($name) - socket not connected" )
unless ( $hash->{CD} );
- Log3( $name, 4, "LGTV_WebOS ($name) - $string" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - $string" );
syswrite( $hash->{CD}, $string );
return;
}
-sub LGTV_WebOS_SocketKeepAlive {
+sub SocketKeepAlive {
my $hash = shift;
my $name = $hash->{NAME};
if (
- int( gettimeofday() ) - int( $hash->{helper}->{lastResponse} ) >
- AttrVal( $name, 'keepAliveCheckTime', 0 ) )
+ int( ::gettimeofday() ) - int( $hash->{helper}->{lastResponse} ) >
+ ::AttrVal( $name, 'keepAliveCheckTime', 0 ) )
{
- LGTV_WebOS_SocketClosePresenceAbsent( $hash, 'absent' );
- Log3( $name, 4,
+ SocketClosePresenceAbsent( $hash, 'absent' );
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - KeepAlive It looks like there no Data more response"
);
}
@@ -734,28 +725,28 @@ sub LGTV_WebOS_SocketKeepAlive {
return;
}
-sub LGTV_WebOS_Read {
+sub Read {
my $hash = shift;
my $name = $hash->{NAME};
my $len;
my $buf;
- Log3( $name, 4, "LGTV_WebOS ($name) - ReadFn started" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - ReadFn started" );
$hash->{helper}->{lastResponse} =
- int( gettimeofday() ); # Check Socket KeepAlive
+ int( ::gettimeofday() ); # Check Socket KeepAlive
$len = sysread( $hash->{CD}, $buf, 10240 );
if ( !defined($len) || !$len ) {
- LGTV_WebOS_Close($hash);
+ Close($hash);
return;
}
unless ( defined $buf ) {
- Log3( $name, 3, "LGTV_WebOS ($name) - no data received" );
+ ::Log3( $name, 3, "LGTV_WebOS ($name) - no data received" );
return;
}
@@ -766,69 +757,74 @@ sub LGTV_WebOS_Read {
$buf = $1;
## use critic
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - received correct JSON string, start response processing: $buf"
);
- LGTV_WebOS_ResponseProcessing( $hash, $buf );
+
+ ResponseProcessing( $hash, $buf );
}
elsif ( $buf =~ /HTTP\/1.1 101 Switching Protocols/x ) {
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - received HTTP data string, start response processing: $buf"
);
- LGTV_WebOS_ResponseProcessing( $hash, $buf );
+
+ ResponseProcessing( $hash, $buf );
}
else {
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - coruppted data found, run LGTV_WebOS_ProcessRead: $buf"
);
- LGTV_WebOS_ProcessRead( $hash, $buf );
+
+ ProcessRead( $hash, $buf );
}
return;
}
-sub LGTV_WebOS_ProcessRead {
- my ( $hash, $data ) = @_;
+sub ProcessRead {
+ my $hash = shift;
+ my $data = shift;
+
my $name = $hash->{NAME};
my $buffer = '';
- Log3( $name, 4, "LGTV_WebOS ($name) - process read" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - process read" );
- if ( defined( $hash->{PARTIAL} ) && $hash->{PARTIAL} ) {
+ if ( exists( $hash->{PARTIAL} ) && $hash->{PARTIAL} ) {
- Log3( $name, 5, "LGTV_WebOS ($name) - PARTIAL: " . $hash->{PARTIAL} );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - PARTIAL: " . $hash->{PARTIAL} );
$buffer = $hash->{PARTIAL};
}
else {
- Log3( $name, 4, "LGTV_WebOS ($name) - No PARTIAL buffer" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - No PARTIAL buffer" );
}
- Log3( $name, 5, "LGTV_WebOS ($name) - Incoming data: " . $data );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - Incoming data: " . $data );
$buffer = $buffer . $data;
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - Current processing buffer (PARTIAL + incoming data): "
. $buffer );
- my ( $json, $tail ) = LGTV_WebOS_ParseMsg( $hash, $buffer );
+ my ( $json, $tail ) = ParseMsg( $hash, $buffer );
while ($json) {
$hash->{LAST_RECV} = time();
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - Decoding JSON message. Length: "
. length($json)
. " Content: "
. $json );
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - Vor Sub: Laenge JSON: "
. length($json)
. " Content: "
@@ -836,12 +832,12 @@ sub LGTV_WebOS_ProcessRead {
. " Tail: "
. $tail );
- LGTV_WebOS_ResponseProcessing( $hash, $json )
+ ResponseProcessing( $hash, $json )
if ( defined($tail) && ($tail) );
- ( $json, $tail ) = LGTV_WebOS_ParseMsg( $hash, $tail );
+ ( $json, $tail ) = ParseMsg( $hash, $tail );
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - Nach Sub: Laenge JSON: "
. length($json)
. " Content: "
@@ -853,19 +849,20 @@ sub LGTV_WebOS_ProcessRead {
$tail = ''
if ( length($tail) > 30000 );
$hash->{PARTIAL} = $tail;
- Log3( $name, 4, "LGTV_WebOS ($name) - PARTIAL lenght: " . length($tail) );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - PARTIAL lenght: " . length($tail) );
- Log3( $name, 5, "LGTV_WebOS ($name) - Tail: " . $tail );
- Log3( $name, 5, "LGTV_WebOS ($name) - PARTIAL: " . $hash->{PARTIAL} );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - Tail: " . $tail );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - PARTIAL: " . $hash->{PARTIAL} );
return;
}
-sub LGTV_WebOS_Handshake {
- my $hash = shift;
+sub Handshake {
+ my $hash = shift;
+
my $name = $hash->{NAME};
my $host = $hash->{HOST};
- my $wsKey = encode_base64( gettimeofday() );
+ my $wsKey = ::encode_base64( ::gettimeofday() );
my $wsHandshakeCmd = "";
$wsHandshakeCmd .= "GET / HTTP/1.1\r\n";
@@ -876,22 +873,22 @@ sub LGTV_WebOS_Handshake {
$wsHandshakeCmd .= "Sec-WebSocket-Version: 13\r\n";
$wsHandshakeCmd .= "Sec-WebSocket-Key: " . $wsKey . "\r\n";
- LGTV_WebOS_Write( $hash, $wsHandshakeCmd );
+ Write( $hash, $wsHandshakeCmd );
$hash->{helper}{wsKey} = $wsKey;
- Log3( $name, 4, "LGTV_WebOS ($name) - send Handshake to WriteFn" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - send Handshake to WriteFn" );
- LGTV_WebOS_TimerStatusRequest($hash);
- Log3( $name, 4, "LGTV_WebOS ($name) - start timer status request" );
+ TimerStatusRequest($hash);
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - start timer status request" );
- LGTV_WebOS_Pairing($hash);
- Log3( $name, 4, "LGTV_WebOS ($name) - start pairing routine" );
+ Pairing($hash);
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - start pairing routine" );
return;
}
-sub LGTV_WebOS_ResponseProcessing {
+sub ResponseProcessing {
my ( $hash, $response ) = @_;
my $name = $hash->{NAME};
@@ -900,14 +897,14 @@ sub LGTV_WebOS_ResponseProcessing {
if ( $response =~ /HTTP\/1.1 101 Switching Protocols/x ) {
my $data = $response;
- my $header = LGTV_WebOS_Header2Hash($data);
+ my $header = Header2Hash($data);
################################
### Handshake for first Connect
- if ( defined( $header->{'Sec-WebSocket-Accept'} ) ) {
+ if ( exists( $header->{'Sec-WebSocket-Accept'} ) ) {
my $keyAccept = $header->{'Sec-WebSocket-Accept'};
- Log3( $name, 5, "LGTV_WebOS ($name) - keyAccept: $keyAccept" );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - keyAccept: $keyAccept" );
my $wsKey = $hash->{helper}{wsKey};
my $expectedResponse = trim(
@@ -924,15 +921,16 @@ sub LGTV_WebOS_ResponseProcessing {
if ( $keyAccept eq $expectedResponse ) {
- Log3( $name, 3,
+ ::Log3( $name, 3,
"LGTV_WebOS ($name) - Sucessfull WS connection to $hash->{HOST}"
);
- readingsSingleUpdate( $hash, 'state', 'on', 1 );
+ ::readingsSingleUpdate( $hash, 'state', 'on', 1 );
}
else {
- LGTV_WebOS_Close($hash);
- Log3( $name, 3,
+ Close($hash);
+
+ ::Log3( $name, 3,
"LGTV_WebOS ($name) - ERROR: Unsucessfull WS connection to $hash->{HOST}"
);
}
@@ -943,49 +941,60 @@ sub LGTV_WebOS_ResponseProcessing {
elsif ( $response =~ m/^{"type":".+}}$/x ) {
- return Log3( $name, 4,
+ return ::Log3( $name, 4,
"LGTV_WebOS ($name) - garbage after JSON object" )
if ( $response =~ m/^{"type":".+}}.+{"type":".+/x );
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - JSON detected, run LGTV_WebOS_WriteReadings"
);
my $json = $response;
- Log3( $name, 4, "LGTV_WebOS ($name) - Corrected JSON String: $json" )
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Corrected JSON String: $json" )
if ($json);
if ( !defined($json) || !($json) ) {
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - Corrected JSON String empty" );
return;
}
- my $decode_json = eval { decode_json( encode_utf8($json) ) };
- if ($@) {
- Log3( $name, 3,
- "LGTV_WebOS ($name) - JSON error while request: $@" );
- return;
+ my $decode_json;
+ try {
+ $decode_json = decode_json( encode_utf8($json) );
}
+ catch {
+ if ( $_->isa('autodie::exception') && $_->matches(':io') ) {
+ Log3( $name, 3,
+ "LGTV_WebOS ($name) autodie - JSON error while request: $_"
+ );
+ return;
+ }
+ else {
+ Log3( $name, 3,
+ "LGTV_WebOS ($name) - JSON error while request: $_" );
+ return;
+ }
+ }; # Note semicolon.
- LGTV_WebOS_WriteReadings( $hash, $decode_json );
+ WriteReadings( $hash, $decode_json );
return;
}
- Log3( $name, 4, "LGTV_WebOS ($name) - no Match found" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - no Match found" );
return;
}
-sub LGTV_WebOS_WriteServiceReadings {
+sub WriteServiceReadings {
my $hash = shift;
my $decode_json = shift;
for my $services ( @{ $decode_json->{payload}{services} } ) {
- readingsBulkUpdateIfChanged(
+ ::readingsBulkUpdateIfChanged(
$hash,
'service_' . $services->{name},
'v.' . $services->{version}
@@ -995,26 +1004,26 @@ sub LGTV_WebOS_WriteServiceReadings {
return;
}
-sub LGTV_WebOS_WriteDeviceReadings {
+sub WriteDeviceReadings {
my $hash = shift;
my $decode_json = shift;
for my $devices ( @{ $decode_json->{payload}{devices} } ) {
- if ( !defined( $hash->{helper}{device}{inputs}{ $devices->{label} } )
+ if ( !exists( $hash->{helper}{device}{inputs}{ $devices->{label} } )
|| !
- defined( $hash->{helper}{device}{inputapps}{ $devices->{appId} } ) )
+ exists( $hash->{helper}{device}{inputapps}{ $devices->{appId} } ) )
{
$hash->{helper}{device}{inputs}
- { makeDeviceName( $devices->{label} ) } = $devices->{appId};
+ { ::makeDeviceName( $devices->{label} ) } = $devices->{appId};
$hash->{helper}{device}{inputapps}{ $devices->{appId} } =
- makeDeviceName( $devices->{label} );
+ ::makeDeviceName( $devices->{label} );
}
- readingsBulkUpdateIfChanged(
+ ::readingsBulkUpdateIfChanged(
$hash,
- 'extInput_' . makeDeviceName( $devices->{label} ),
+ 'extInput_' . ::makeDeviceName( $devices->{label} ),
'connect_' . $devices->{connected}
);
}
@@ -1022,7 +1031,7 @@ sub LGTV_WebOS_WriteDeviceReadings {
return;
}
-sub LGTV_WebOS_WriteProgramlistReadings {
+sub WriteProgramlistReadings {
my $hash = shift;
my $decode_json = shift;
@@ -1031,49 +1040,27 @@ sub LGTV_WebOS_WriteProgramlistReadings {
for my $programList ( @{ $decode_json->{payload}{programList} } ) {
if (
- str2time(
- LGTV_WebOS_FormartStartEndTime( $programList->{localEndTime} )
- ) > time()
- )
+ ::str2time( FormartStartEndTime( $programList->{localEndTime} ) ) >
+ time() )
{
if ( $count < 1 ) {
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle',
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle',
$programList->{programName} );
- readingsBulkUpdateIfChanged(
- $hash,
- 'channelCurrentStartTime',
- LGTV_WebOS_FormartStartEndTime(
- $programList->{localStartTime}
- )
- );
- readingsBulkUpdateIfChanged(
- $hash,
- 'channelCurrentEndTime',
- LGTV_WebOS_FormartStartEndTime(
- $programList->{localEndTime}
- )
- );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentStartTime',
+ FormartStartEndTime( $programList->{localStartTime} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentEndTime',
+ FormartStartEndTime( $programList->{localEndTime} ) );
}
elsif ( $count < 2 ) {
- readingsBulkUpdateIfChanged( $hash, 'channelNextTitle',
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextTitle',
$programList->{programName} );
- readingsBulkUpdateIfChanged(
- $hash,
- 'channelNextStartTime',
- LGTV_WebOS_FormartStartEndTime(
- $programList->{localStartTime}
- )
- );
- readingsBulkUpdateIfChanged(
- $hash,
- 'channelNextEndTime',
- LGTV_WebOS_FormartStartEndTime(
- $programList->{localEndTime}
- )
- );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextStartTime',
+ FormartStartEndTime( $programList->{localStartTime} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextEndTime',
+ FormartStartEndTime( $programList->{localEndTime} ) );
}
$count++;
@@ -1084,53 +1071,53 @@ sub LGTV_WebOS_WriteProgramlistReadings {
return;
}
-sub LGTV_WebOS_WriteMuteReadings {
+sub WriteMuteReadings {
my $hash = shift;
my $decode_json = shift;
if (
- defined( $decode_json->{payload}{'mute'} )
+ exists( $decode_json->{payload}{'mute'} )
&& ( $decode_json->{payload}{'mute'} eq 'true'
|| $decode_json->{payload}{'mute'} == 1 )
)
{
- readingsBulkUpdateIfChanged( $hash, 'mute', 'on' );
+ ::readingsBulkUpdateIfChanged( $hash, 'mute', 'on' );
}
- elsif ( defined( $decode_json->{payload}{'mute'} ) ) {
+ elsif ( exists( $decode_json->{payload}{'mute'} ) ) {
if ( $decode_json->{payload}{'mute'} eq 'false'
|| $decode_json->{payload}{'mute'} == 0 )
{
- readingsBulkUpdateIfChanged( $hash, 'mute', 'off' );
+ ::readingsBulkUpdateIfChanged( $hash, 'mute', 'off' );
}
}
if (
- defined( $decode_json->{payload}{'muted'} )
+ exists( $decode_json->{payload}{'muted'} )
&& ( $decode_json->{payload}{'muted'} eq 'true'
|| $decode_json->{payload}{'muted'} == 1 )
)
{
- readingsBulkUpdateIfChanged( $hash, 'mute', 'on' );
+ ::readingsBulkUpdateIfChanged( $hash, 'mute', 'on' );
}
elsif (
- defined( $decode_json->{payload}{'muted'} )
+ exists( $decode_json->{payload}{'muted'} )
&& ( $decode_json->{payload}{'muted'} eq 'false'
|| $decode_json->{payload}{'muted'} == 0 )
)
{
- readingsBulkUpdateIfChanged( $hash, 'mute', 'off' );
+ ::readingsBulkUpdateIfChanged( $hash, 'mute', 'off' );
}
return;
}
-sub LGTV_WebOS_Write3dReadings {
+sub Write3dReadings {
my $hash = shift;
my $decode_json = shift;
@@ -1138,23 +1125,23 @@ sub LGTV_WebOS_Write3dReadings {
|| $decode_json->{payload}{status3D}{status} == 0 )
{
- readingsBulkUpdateIfChanged( $hash, '3D', 'off' );
+ ::readingsBulkUpdateIfChanged( $hash, '3D', 'off' );
}
elsif ($decode_json->{payload}{status3D}{status} eq 'true'
|| $decode_json->{payload}{status3D}{status} == 1 )
{
- readingsBulkUpdateIfChanged( $hash, '3D', 'on' );
+ ::readingsBulkUpdateIfChanged( $hash, '3D', 'on' );
}
- readingsBulkUpdateIfChanged( $hash, '3DMode',
+ ::readingsBulkUpdateIfChanged( $hash, '3DMode',
$decode_json->{payload}{status3D}{pattern} );
return;
}
-sub LGTV_WebOS_WriteAppIdReadings {
+sub WriteAppIdReadings {
my $hash = shift;
my $decode_json = shift;
@@ -1163,39 +1150,39 @@ sub LGTV_WebOS_WriteAppIdReadings {
$decode_json->{payload}{appId} =~ /com.webos.app.externalinput/x
|| $decode_json->{payload}{appId} =~ /com.webos.app.hdmi/x
)
- && defined(
+ && exists(
$hash->{helper}{device}{inputapps}{ $decode_json->{payload}{appId} }
)
&& $hash->{helper}{device}{inputapps}{ $decode_json->{payload}{appId} }
)
{
- readingsBulkUpdateIfChanged( $hash, 'input',
+ ::readingsBulkUpdateIfChanged( $hash, 'input',
$hash->{helper}{device}{inputapps}{ $decode_json->{payload}{appId} }
);
- readingsBulkUpdateIfChanged( $hash, 'launchApp', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'launchApp', '-' );
}
- elsif ( defined( $openAppsPackageName{ $decode_json->{payload}{appId} } )
+ elsif ( exists( $openAppsPackageName{ $decode_json->{payload}{appId} } )
&& $openAppsPackageName{ $decode_json->{payload}{appId} } )
{
- readingsBulkUpdateIfChanged( $hash, 'launchApp',
+ ::readingsBulkUpdateIfChanged( $hash, 'launchApp',
$openAppsPackageName{ $decode_json->{payload}{appId} } );
- readingsBulkUpdateIfChanged( $hash, 'input', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'input', '-' );
}
return;
}
-sub LGTV_WebOS_WriteTypeReadings {
+sub WriteTypeReadings {
my $hash = shift;
my $decode_json = shift;
my $response;
if ( $decode_json->{type} eq 'registered'
- && defined( $decode_json->{payload}{'client-key'} ) )
+ && exists( $decode_json->{payload}{'client-key'} ) )
{
$hash->{helper}{device}{registered} = 1;
@@ -1208,12 +1195,12 @@ sub LGTV_WebOS_WriteTypeReadings {
|| $decode_json->{payload}{returnValue} == 1 )
)
|| ( $decode_json->{type} eq 'registered' )
- && defined( $decode_json->{payload}{'client-key'} )
+ && exists( $decode_json->{payload}{'client-key'} )
)
{
$response = 'ok';
- readingsBulkUpdateIfChanged( $hash, 'pairing', 'paired' );
+ ::readingsBulkUpdateIfChanged( $hash, 'pairing', 'paired' );
$hash->{helper}{device}{runsetcmd} =
$hash->{helper}{device}{runsetcmd} - 1
if ( $hash->{helper}{device}{runsetcmd} > 0 );
@@ -1229,7 +1216,7 @@ sub LGTV_WebOS_WriteTypeReadings {
'401 insufficient permissions (not registered)' )
{
- readingsBulkUpdateIfChanged( $hash, 'pairing', 'unpaired' );
+ ::readingsBulkUpdateIfChanged( $hash, 'pairing', 'unpaired' );
}
$hash->{helper}{device}{runsetcmd} =
@@ -1240,95 +1227,95 @@ sub LGTV_WebOS_WriteTypeReadings {
return $response;
}
-sub LGTV_WebOS_WriteReadings {
+sub WriteReadings {
my ( $hash, $decode_json ) = @_;
my $name = $hash->{NAME};
my $response;
- Log3( $name, 4, "LGTV_WebOS ($name) - Beginn Readings writing" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Beginn Readings writing" );
- readingsBeginUpdate($hash);
+ ::readingsBeginUpdate($hash);
if ( ref( $decode_json->{payload}{services} ) eq "ARRAY"
&& scalar( @{ $decode_json->{payload}{services} } ) > 0 )
{
- LGTV_WebOS_WriteServiceReadings( $hash, $decode_json );
+ WriteServiceReadings( $hash, $decode_json );
}
elsif ( ref( $decode_json->{payload}{devices} ) eq "ARRAY"
&& scalar( @{ $decode_json->{payload}{devices} } ) > 0 )
{
- LGTV_WebOS_WriteDeviceReadings( $hash, $decode_json );
+ WriteDeviceReadings( $hash, $decode_json );
}
elsif ( ref( $decode_json->{payload}{programList} ) eq "ARRAY"
&& scalar( @{ $decode_json->{payload}{programList} } ) > 0 )
{
- LGTV_WebOS_WriteProgramlistReadings( $hash, $decode_json );
+ WriteProgramlistReadings( $hash, $decode_json );
}
- if ( defined( $decode_json->{payload}{'mute'} )
- || defined( $decode_json->{payload}{'muted'} ) )
+ if ( exists( $decode_json->{payload}{'mute'} )
+ || exists( $decode_json->{payload}{'muted'} ) )
{
- LGTV_WebOS_WriteMuteReadings( $hash, $decode_json );
+ WriteMuteReadings( $hash, $decode_json );
}
- elsif ( defined( $decode_json->{payload}{status3D}{status} ) ) {
- LGTV_WebOS_Write3dReadings( $hash, $decode_json );
+ elsif ( exists( $decode_json->{payload}{status3D}{status} ) ) {
+ Write3dReadings( $hash, $decode_json );
}
- elsif ( defined( $decode_json->{payload}{appId} ) ) {
- LGTV_WebOS_WriteAppIdReadings( $hash, $decode_json );
+ elsif ( exists( $decode_json->{payload}{appId} ) ) {
+ WriteAppIdReadings( $hash, $decode_json );
}
- if ( defined( $decode_json->{type} ) ) {
- $response = LGTV_WebOS_WriteTypeReadings( $hash, $decode_json );
+ if ( exists( $decode_json->{type} ) ) {
+ $response = WriteTypeReadings( $hash, $decode_json );
}
- readingsBulkUpdateIfChanged( $hash, 'lgKey',
+ ::readingsBulkUpdateIfChanged( $hash, 'lgKey',
$decode_json->{payload}{'client-key'} )
- if ( defined( $decode_json->{payload}{'client-key'} ) );
- readingsBulkUpdateIfChanged( $hash, 'volume',
+ if ( exists( $decode_json->{payload}{'client-key'} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'volume',
$decode_json->{payload}{'volume'} )
- if ( defined( $decode_json->{payload}{'volume'} ) );
- readingsBulkUpdateIfChanged( $hash, 'lastResponse', $response )
+ if ( exists( $decode_json->{payload}{'volume'} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'lastResponse', $response )
if ( defined($response) );
- if ( ReadingsVal( $name, 'launchApp', 'none' ) eq 'TV' ) {
+ if ( ::ReadingsVal( $name, 'launchApp', 'none' ) eq 'TV' ) {
- readingsBulkUpdateIfChanged( $hash, 'channel',
+ ::readingsBulkUpdateIfChanged( $hash, 'channel',
$decode_json->{payload}{'channelNumber'} )
- if ( defined( $decode_json->{payload}{'channelNumber'} ) );
- readingsBulkUpdateIfChanged( $hash, 'channelName',
+ if ( exists( $decode_json->{payload}{'channelNumber'} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelName',
$decode_json->{payload}{'channelName'} )
- if ( defined( $decode_json->{payload}{'channelName'} ) );
- readingsBulkUpdateIfChanged( $hash, 'channelMedia',
+ if ( exists( $decode_json->{payload}{'channelName'} ) );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelMedia',
$decode_json->{payload}{'channelTypeName'} )
- if ( defined( $decode_json->{payload}{'channelTypeName'} ) );
+ if ( exists( $decode_json->{payload}{'channelTypeName'} ) );
}
else {
- readingsBulkUpdateIfChanged( $hash, 'channelName', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channel', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelMedia', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentStartTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelCurrentEndTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextTitle', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextStartTime', '-' );
- readingsBulkUpdateIfChanged( $hash, 'channelNextEndTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelName', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channel', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelMedia', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentTitle', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentStartTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelCurrentEndTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextTitle', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextStartTime', '-' );
+ ::readingsBulkUpdateIfChanged( $hash, 'channelNextEndTime', '-' );
}
- readingsBulkUpdateIfChanged( $hash, 'state', 'on' );
+ ::readingsBulkUpdateIfChanged( $hash, 'state', 'on' );
- readingsEndUpdate( $hash, 1 );
+ ::readingsEndUpdate( $hash, 1 );
return;
}
-sub LGTV_WebOS_Pairing {
+sub Pairing {
my $hash = shift;
my $name = $hash->{NAME};
- Log3( $name, 4, "LGTV_WebOS ($name) - HASH handshakePayload" );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - HASH handshakePayload" );
my %handshakePayload = (
"pairingType" => "PROMPT",
@@ -1394,17 +1381,17 @@ sub LGTV_WebOS_Pairing {
my $usedHandshake = \%handshakePayload;
- my $key = ReadingsVal( $name, 'lgKey', '' );
+ my $key = ::ReadingsVal( $name, 'lgKey', '' );
$usedHandshake->{'client-key'} = $key if ( defined($key) );
- LGTV_WebOS_CreateSendCommand( $hash, undef, $usedHandshake, 'register' );
- Log3( $name, 4, "LGTV_WebOS ($name) - Send pairing informations" );
+ CreateSendCommand( $hash, undef, $usedHandshake, 'register' );
+ ::Log3( $name, 4, "LGTV_WebOS ($name) - Send pairing informations" );
return;
}
-sub LGTV_WebOS_CreateSendCommand {
+sub CreateSendCommand {
my ( $hash, $uri, $payload, $type ) = @_;
my $name = $hash->{NAME};
@@ -1412,25 +1399,40 @@ sub LGTV_WebOS_CreateSendCommand {
$type = 'request' if ( !defined($type) );
my $command = {};
- $command->{'client-key'} = ReadingsVal( $name, 'lgKey', '' )
+ $command->{'client-key'} = ::ReadingsVal( $name, 'lgKey', '' )
if ( $type ne 'register' );
- $command->{id} = $type . "_" . gettimeofday();
+ $command->{id} = $type . "_" . ::gettimeofday();
$command->{type} = $type;
$command->{uri} = $uri if ($uri);
$command->{payload} = $payload if ( defined($payload) );
-#Log3( $name, 5, "LGTV_WebOS ($name) - Payload Message: $command->{payload}{message}" );
+#::Log3( $name, 5, "LGTV_WebOS ($name) - Payload Message: $command->{payload}{message}" );
- my $cmd = encode_json($command);
+ my $cmd;
+ try {
+ $cmd = encode_json($command);
+ }
+ catch {
+ if ( $_->isa('autodie::exception') && $_->matches(':io') ) {
+ Log3( $name, 3,
+ "LGTV_WebOS ($name) - can't $cmd encode to json: $_" );
+ return;
+ }
+ else {
+ Log3( $name, 3,
+ "LGTV_WebOS ($name) - can't $cmd encode to json: $_" );
+ return;
+ }
+ };
- Log3( $name, 5, "LGTV_WebOS ($name) - Sending command: $cmd" );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - Sending command: $cmd" );
- LGTV_WebOS_Write( $hash, LGTV_WebOS_Hybi10Encode( $cmd, "text", 1 ) );
+ Write( $hash, Hybi10Encode( $cmd, "text", 1 ) );
return;
}
-sub LGTV_WebOS_Hybi10Encode {
+sub Hybi10Encode {
my $payload = shift;
my $type = shift // 'text';
my $masked = shift // 1;
@@ -1528,86 +1530,87 @@ sub LGTV_WebOS_Hybi10Encode {
return $frame;
}
-sub LGTV_WebOS_GetAudioStatus {
+sub GetAudioStatus {
my $hash = shift;
my $name = $hash->{NAME};
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_GetAudioStatus: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{getAudioStatus}, undef )
+ CreateSendCommand( $hash, $lgCommands{getAudioStatus}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
}
-sub LGTV_WebOS_GetCurrentChannel {
+sub GetCurrentChannel {
my $hash = shift;
my $name = $hash->{NAME};
- RemoveInternalTimer( $hash, 'LGTV_WebOS_GetCurrentChannel' );
- Log3( $name, 4,
+ ::RemoveInternalTimer( $hash,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetCurrentChannel );
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_GetCurrentChannel: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{getCurrentChannel}, undef )
+ CreateSendCommand( $hash, $lgCommands{getCurrentChannel}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
}
-sub LGTV_WebOS_GetForgroundAppInfo {
+sub GetForgroundAppInfo {
my $hash = shift;
my $name = $hash->{NAME};
- RemoveInternalTimer( $hash, 'LGTV_WebOS_GetForgroundAppInfo' );
- Log3( $name, 4,
+ ::RemoveInternalTimer( $hash,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetForgroundAppInfo );
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_GetForgroundAppInfo: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{getForegroundAppInfo},
- undef )
+ CreateSendCommand( $hash, $lgCommands{getForegroundAppInfo}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
}
-sub LGTV_WebOS_GetExternalInputList {
+sub GetExternalInputList {
my $hash = shift;
my $name = $hash->{NAME};
- RemoveInternalTimer( $hash, 'LGTV_WebOS_GetExternalInputList' );
- Log3( $name, 4,
+ ::RemoveInternalTimer( $hash,
+ \&FHEM::Devices::LGTV::LGTVWebOS::GetExternalInputList );
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_GetExternalInputList: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{getExternalInputList},
- undef )
+ CreateSendCommand( $hash, $lgCommands{getExternalInputList}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
}
-sub LGTV_WebOS_Get3DStatus {
+sub Get3DStatus {
my $hash = shift;
my $name = $hash->{NAME};
- RemoveInternalTimer( $hash, 'LGTV_WebOS_Get3DStatus' );
- Log3( $name, 4,
+ ::RemoveInternalTimer( $hash,
+ \&FHEM::Devices::LGTV::LGTVWebOS::Get3DStatus );
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_Get3DStatus: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{get3DStatus}, undef )
+ CreateSendCommand( $hash, $lgCommands{get3DStatus}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
}
-sub LGTV_WebOS_GetChannelProgramInfo {
+sub GetChannelProgramInfo {
my $hash = shift;
my $name = $hash->{NAME};
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - LGTV_WebOS_GetChannelProgramInfo: "
. $hash->{helper}{device}{runsetcmd} );
- LGTV_WebOS_CreateSendCommand( $hash, $lgCommands{getChannelProgramInfo},
- undef )
+ CreateSendCommand( $hash, $lgCommands{getChannelProgramInfo}, undef )
if ( $hash->{helper}{device}{runsetcmd} == 0 );
return;
@@ -1616,7 +1619,7 @@ sub LGTV_WebOS_GetChannelProgramInfo {
#############################################
### my little Helper
-sub LGTV_WebOS_ParseMsg {
+sub ParseMsg {
my $hash = shift;
my $buffer = shift;
@@ -1630,14 +1633,14 @@ sub LGTV_WebOS_ParseMsg {
for my $c ( split //, $buffer ) {
if ( $jsonopen == $jsonclose && $jsonopen > 0 ) {
$tail .= $c;
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - $jsonopen == $jsonclose && $jsonopen > 0"
);
}
elsif ( ( $jsonopen == $jsonclose ) && ( $c ne '{' ) ) {
- Log3( $name, 5,
+ ::Log3( $name, 5,
"LGTV_WebOS ($name) - Garbage character before message: "
. $c );
@@ -1665,11 +1668,11 @@ sub LGTV_WebOS_ParseMsg {
}
}
- Log3( $name, 5, "LGTV_WebOS ($name) - return msg: $msg and tail: $tail" );
+ ::Log3( $name, 5, "LGTV_WebOS ($name) - return msg: $msg and tail: $tail" );
return ( $msg, $tail );
}
-sub LGTV_WebOS_Header2Hash {
+sub Header2Hash {
my $string = shift;
my %hash = ();
@@ -1684,7 +1687,7 @@ sub LGTV_WebOS_Header2Hash {
return \%hash;
}
-sub LGTV_WebOS_FormartStartEndTime {
+sub FormartStartEndTime {
my $string = shift;
my @timeArray = split( ',', $string );
@@ -1694,19 +1697,23 @@ sub LGTV_WebOS_FormartStartEndTime {
}
############ Presence Erkennung Begin #################
-sub LGTV_WebOS_Presence {
+sub Presence {
my $hash = shift;
my $name = $hash->{NAME};
- $hash->{helper}{RUNNING_PID} =
- BlockingCall( "LGTV_WebOS_PresenceRun", $name . '|' . $hash->{HOST},
- "LGTV_WebOS_PresenceDone", 5, "LGTV_WebOS_PresenceAborted", $hash )
- unless ( exists( $hash->{helper}{RUNNING_PID} ) );
+ $hash->{helper}{RUNNING_PID} = ::BlockingCall(
+ 'FHEM::Devices::LGTV::LGTVWebOS::PresenceRun',
+ $name . '|' . $hash->{HOST},
+ 'FHEM::Devices::LGTV::LGTVWebOS::PresenceDone',
+ 5,
+ 'FHEM::Devices::LGTV::LGTVWebOS::PresenceAborted',
+ $hash
+ ) unless ( exists( $hash->{helper}{RUNNING_PID} ) );
return;
}
-sub LGTV_WebOS_PresenceRun {
+sub PresenceRun {
my $string = shift;
my ( $name, $host ) = split( "\\|", $string );
@@ -1715,10 +1722,10 @@ sub LGTV_WebOS_PresenceRun {
$tmp = qx(ping -c 3 -w 2 $host 2>&1); ## no critic (Backtick operator used)
- if ( defined($tmp) && $tmp ne "" ) {
+ if ( defined($tmp) && $tmp ne '' ) {
chomp $tmp;
- Log3( $name, 4,
+ ::Log3( $name, 4,
"LGTV_WebOS ($name) - ping command returned with output:\n$tmp" );
$response = $name . '|' . (
$tmp =~
@@ -1734,14 +1741,13 @@ sub LGTV_WebOS_PresenceRun {
$response = "$name|Could not execute ping command";
}
- Log3( $name, 4,
-"Sub LGTV_WebOS_PresenceRun ($name) - Sub finish, Call LGTV_WebOS_PresenceDone"
- );
+ ::Log3( $name, 4,
+ "sub PresenceRun ($name) - Sub finish, Call LGTV_WebOS_PresenceDone" );
return $response;
}
-sub LGTV_WebOS_PresenceDone {
+sub PresenceDone {
my $string = shift;
my ( $name, $response ) = split( "\\|", $string );
@@ -1749,50 +1755,52 @@ sub LGTV_WebOS_PresenceDone {
delete( $hash->{helper}{RUNNING_PID} );
- Log3( $name, 4,
-"Sub LGTV_WebOS_PresenceDone ($name) - Helper is disabled. Stop processing"
- ) if ( $hash->{helper}{DISABLED} );
- return if ( $hash->{helper}{DISABLED} );
+ if ( exists( $hash->{helper}{DISABLED} ) ) {
+ ::Log3( $name, 4,
+ "sub PresenceDone ($name) - Helper is disabled. Stop processing" );
- readingsSingleUpdate( $hash, 'presence', $response, 1 );
+ return;
+ }
- LGTV_WebOS_SocketClosePresenceAbsent( $hash, $response );
+ ::readingsSingleUpdate( $hash, 'presence', $response, 1 );
- Log3( $name, 4, "Sub LGTV_WebOS_PresenceDone ($name) - presence done" );
+ SocketClosePresenceAbsent( $hash, $response );
+
+ ::Log3( $name, 4, "sub PresenceDone ($name) - presence done" );
return;
}
-sub LGTV_WebOS_PresenceAborted {
+sub PresenceAborted {
my $hash = shift;
my $name = $hash->{NAME};
delete( $hash->{helper}{RUNNING_PID} );
- readingsSingleUpdate( $hash, 'presence', 'pingPresence timedout', 1 );
+ ::readingsSingleUpdate( $hash, 'presence', 'pingPresence timedout', 1 );
- Log3( $name, 4,
-"Sub LGTV_WebOS_PresenceAborted ($name) - The BlockingCall Process terminated unexpectedly. Timedout!"
+ ::Log3( $name, 4,
+"sub PresenceAborted ($name) - The BlockingCall Process terminated unexpectedly. Timedout!"
);
return;
}
-sub LGTV_WebOS_SocketClosePresenceAbsent {
+sub SocketClosePresenceAbsent {
my $hash = shift;
my $presence = shift;
my $name = $hash->{NAME};
- LGTV_WebOS_Close($hash)
- if ( $presence eq 'absent' && !IsDisabled($name) && $hash->{CD} )
+ Close($hash)
+ if ( $presence eq 'absent' && !::IsDisabled($name) && $hash->{CD} )
; # https://forum.fhem.de/index.php/topic,66671.msg694578.html#msg694578
# Sobald pingPresence absent meldet und der Socket noch steht soll er geschlossen werden, da sonst FHEM nach 4-6 min für 10 min blockiert
return;
}
-sub LGTV_WebOS_WakeUp_Udp {
+sub WakeUp_Udp {
my ( $hash, $mac_addr, $host, $port ) = @_;
my $name = $hash->{NAME};
@@ -1800,18 +1808,17 @@ sub LGTV_WebOS_WakeUp_Udp {
my $sock = IO::Socket::INET->new( Proto => 'udp' ) or warn "socket : $!\n";
if ( !$sock ) {
- Log3( $name, 3,
- "Sub LGTV_WebOS_WakeUp_Udp ($name) - Can't create WOL socket" );
+ ::Log3( $name, 3, "sub WakeUp_Udp ($name) - Can't create WOL socket" );
return 1;
}
- my $ip_addr = inet_aton($host);
- my $sock_addr = sockaddr_in( $port, $ip_addr );
+ my $ip_addr = ::inet_aton($host);
+ my $sock_addr = ::sockaddr_in( $port, $ip_addr );
$mac_addr =~ s/://xg;
my $packet =
pack( 'C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $mac_addr x 16 );
- setsockopt( $sock, SOL_SOCKET, SO_BROADCAST, 1 )
+ setsockopt( $sock, ::SOL_SOCKET, ::SO_BROADCAST, 1 )
or warn "setsockopt : $!\n";
send( $sock, $packet, 0, $sock_addr ) or warn "send : $!\n";
close($sock);
@@ -1823,326 +1830,4 @@ sub LGTV_WebOS_WakeUp_Udp {
1;
-=pod
-=item device
-=item summary Controls LG SmartTVs run with WebOS Operating System
-=item summary_DE Steuert LG SmartTVs mit WebOS Betriebssystem
-
-=begin html
-
-
-LGTV_WebOS
-
-
- This module controls SmartTVs from LG based on WebOS as operation system via network. It offers to swtich the TV channel, start and switch applications, send remote control commands, as well as to query the actual status.
-
- Definition define <name> LGTV_WebOS <IP-Address>
-
-
-
- When an LGTV_WebOS-Module is defined, an internal routine is triggered which queries the TV's status every 15s and triggers respective Notify / FileLog Event definitions.
-
-
-
-
-
-
- define TV LGTV_WebOS 192.168.0.10
-
-
- Set-Commands set <Name> <Command> [<Parameter>]
-
-
- The following commands are supported in the actual version:
-
-
-
-
-
- - connect - Connects to the TV at the defined address. When triggered the first time, a pairing is conducted
- - pairing - Sends a pairing request to the TV which needs to be confirmed by the user with remote control
- - screenMsg <Text> - Displays a message for 3-5s on the TV in the top right corner of the screen
- - mute on, off - Turns volume to mute. Depending on the audio connection, this needs to be set on the AV Receiver (see volume)
- - volume 0-100, Slider - Sets the volume. Depending on the audio connection, this needs to be set on the AV Receiver (see mute)
- - volumeUp - Increases the volume by 1
- - volumeDown - Decreases the volume by 1
- - channelUp - Switches the channel to the next one
- - channelDown - Switches the channel to the previous one
- - getServiceList - Queries the running services on WebOS (in beta phase)
- - on - Turns the TV on, depending on type of device. Only working when LAN or Wifi connection remains active during off state.
- - off - Turns the TV off, when an active connection is established
- - launchApp <Application> - Activates an application out of the following list (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV)
Note: TV is an application in LG's terms and not an input connection
- - 3D on,off - 3D Mode is turned on and off. Depending on type of TV there might be different modes (e.g. Side-by-Side, Top-Bottom)
- - stop - Stop command (depending on application)
- - play - Play command (depending on application)
- - pause - Pause command (depending on application)
- - rewind - Rewind command (depending on application)
- - fastForward - Fast Forward command (depending on application)
- - clearInputList - Clears list of Inputs
- - input - Selects the input connection (depending on the actual TV type and connected devices)
e.g.: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)
-
-
-
- Get-Command get <Name> <Readingname>
-
-
- Currently, GET reads back the values of the current readings. Please see below for a list of Readings / Generated Events.
-
-
-
Attributes
-
-
- - disable
- Optional attribute to deactivate the recurring status updates. Manual trigger of update is alsways possible.
- Valid Values: 0 => recurring status updates, 1 => no recurring status updates.
-
-
-
-
- - channelGuide
- Optional attribute to deactivate the recurring TV Guide update. Depending on TV and FHEM host, this causes significant network traffic and / or CPU load
- Valid Values: 0 => no recurring TV Guide updates, 1 => recurring TV Guide updates.
-
-
-
-
- - pingPresence
- current state of ping presence from TV. create a reading presence with values absent or present.
-
-
-
-
- - keepAliveCheckTime
- value in seconds - keepAliveCheck is check read data input from tcp socket and prevented FHEM freeze.
-
-
-
-
- - wakeOnLanMAC
- Network MAC Address of the LG TV Networkdevice.
-
-
-
-
- - wakeOnLanBroadcast
- Broadcast Address of the Network - wakeOnLanBroadcast <network>.255
-
-
-
-
- - wakeupCmd
- Set a command to be executed when turning on an absent device. Can be an FHEM command or Perl command in {}.
-
-
-
-
-=end html
-
-=begin html_DE
-
-
-LGTV_WebOS
-
-
- Dieses Modul steuert SmartTV's des Herstellers LG mit dem Betriebssystem WebOS über die Netzwerkschnittstelle. Es bietet die Möglichkeit den aktuellen TV Kanal zu steuern, sowie Apps zu starten, Fernbedienungsbefehle zu senden, sowie den aktuellen Status abzufragen.
-
-
Definition define <name> LGTV_WebOS <IP-Addresse>
-
-
- Bei der Definition eines LGTV_WebOS-Moduls wird eine interne Routine in Gang gesetzt, welche regelmäßig alle 15s den Status des TV abfragt und entsprechende Notify-/FileLog-Definitionen triggert.
-
-
-
-
- Beispiel: define TV LGTV_WebOS 192.168.0.10
-
-
- Set-Kommandos set <Name> <Kommando> [<Parameter>]
-
-
- Aktuell werden folgende Kommandos unterstützt.
-
-
-
-
-
-
- - connect - Verbindet sich zum Fernseher unter der IP wie definiert, führt beim ersten mal automatisch ein pairing durch
- - pairing - Berechtigungsanfrage an den Fernseher, hier muss die Anfrage mit der Fernbedienung bestätigt werden
- - screenMsg <Text> - zeigt für ca 3-5s eine Nachricht auf dem Fernseher oben rechts an
- - mute on, off - Schaltet den Fernseher Stumm, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe Volume)
- - volume 0-100, Schieberegler - Setzt die Lautstärke des Fernsehers, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe mute)
- - volumeUp - Erhöht die Lautstärke um den Wert 1
- - volumeDown - Verringert die Lautstärke um den Wert 1
- - channelUp - Schaltet auf den nächsten Kanal um
- - channelDown - Schaltet auf den vorherigen Kanal um
- - getServiceList - Fragrt die Laufenden Dienste des Fernsehers an (derzeit noch in Beta-Phase)
- - on - Schaltet den Fernseher ein, wenn WLAN oder LAN ebenfalls im Aus-Zustand aktiv ist (siehe Bedienungsanleitung da Typabhängig)
- - off - Schaltet den Fernseher aus, wenn eine Connection aktiv ist
- - launchApp <Anwendung> - Aktiviert eine Anwendung aus der Liste (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV)
Achtung: TV ist hier eine Anwendung, und kein Geräteeingang
- - 3D on,off - 3D Modus kann hier ein- und ausgeschaltet werden, je nach Fernseher können mehrere 3D Modi unterstützt werden (z.B. Side-by-Side, Top-Bottom)
- - stop - Stop-Befehl (anwendungsabhängig)
- - play - Play-Befehl (anwendungsabhängig)
- - pause - Pause-Befehl (anwendungsabhängig)
- - rewind - Zurückspulen-Befehl (anwendungsabhängig)
- - fastForward - Schneller-Vorlauf-Befehl (anwendungsabhängig)
- - clearInputList - Löscht die Liste der Geräteeingänge
- - input - Wählt den Geräteeingang aus (Abhängig von Typ und angeschossenen Geräten)
Beispiele: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)
-
-
-
-
- Get-Kommandos get <Name> <Readingname>
-
-
- Aktuell stehen via GET lediglich die Werte der Readings zur Verfügung. Eine genaue Auflistung aller möglichen Readings folgen unter "Generierte Readings/Events".
-
-
-
Attribute
-
-
-
- - disable
- Optionales Attribut zur Deaktivierung des zyklischen Status-Updates. Ein manuelles Update via statusRequest-Befehl ist dennoch möglich.
-
-
-
-
-
- Mögliche Werte: 0 => zyklische Status-Updates, 1 => keine zyklischen Status-Updates.
-
-
-
-
-
- - channelGuide
- Optionales Attribut zur Deaktivierung der zyklischen Updates des TV-Guides, dieses beansprucht je nach Hardware einigen Netzwerkverkehr und Prozessorlast
-
-
-
-
-
- Mögliche Werte: 0 => keine zyklischen TV-Guide-Updates, 1 => zyklische TV-Guide-Updates
-
-
-
-
-
- - wakeOnLanMAC
- MAC Addresse der Netzwerkkarte vom LG TV
-
-
-
-
-
-
- - wakeOnLanBroadcast
- Broadcast Netzwerkadresse - wakeOnLanBroadcast <netzwerk>.255
-
-
-
-
-
-
- - pingPresence
- Mögliche Werte: 0 => presence via ping deaktivert, 1 => presence via ping aktiviert
-
-
-
-
-
-
- - keepAliveCheckTime
- Wert in Sekunden - keepAliveCheckTime
- kontrolliert in einer bestimmten Zeit ob noch Daten über die TCP Schnittstelle kommen und verhindert somit FHEM Freezes
-
-
-
-
-
-
- - wakeupCmd
- Befehl zum Einschalten des LG TV. Möglich ist ein FHEM Befehl oder Perl in {}.
-
-
-
-
Generierte Readings/Events:
-
-
- - 3D - Status des 3D-Wiedergabemodus ("on" => 3D Wiedergabemodus aktiv, "off" => 3D Wiedergabemodus nicht aktiv)
- - 3DMode - Anzeigemodus (2d, 2dto3d, side_side_half, line_interleave_half, column_interleave, check_board)
- - channel - Die Nummer des aktuellen TV-Kanals
- - channelName - Der Name des aktuellen TV-Kanals
- - channelMedia - Senderinformation
- - channelCurrentEndTime - Ende der laufenden Sendung (Beta)
- - channelCurrentStartTime - Start der laufenden Sendung (Beta)
- - channelCurrentTitle - Der Name der laufenden Sendung (Beta)
- - channelNextEndTime - Ende der nächsten Sendung (Beta)
- - channelNextStartTime - Start der nächsten Sendung (Beta)
- - channelNextTitle - Der Name der nächsten Sendung (Beta)
- - extInput_<Geräteeingang> - Status der Eingangsquelle (connect_true, connect_false)
- - input - Derzeit aktiver Geräteeingang
- - lastResponse - Status der letzten Anfrage (ok, error <Fehlertext>)
- - launchApp <Anwendung> - Gegenwärtige aktive Anwendung
- - lgKey - Der Client-Key, der für die Verbindung verwendet wird
- - mute on,off - Der aktuelle Stumm-Status ("on" => Stumm, "off" => Laut)
- - pairing paired, unpaired - Der Status des Pairing
- - presence absent, present - Der aktuelle Power-Status ("present" => eingeschaltet, "absent" => ausgeschaltet)
- - state on, off - Status des Fernsehers (ähnlich presence)
- - volume - Der aktuelle Lautstärkepegel -1, 0-100 (-1 invalider Wert)
-
-
-
-=end html_DE
-
-=for :application/json;q=META.json 82_LGTV_WebOS.pm
-{
- "abstract": "Module for Controls LG SmartTVs run with WebOS Operating System",
- "x_lang": {
- "de": {
- "abstract": "Modul zur Steuerung von LG SmartTVs mit WebOS Betriebssystem"
- }
- },
- "keywords": [
- "fhem-mod-device",
- "fhem-core",
- "Multimedia",
- "TV",
- "LG"
- ],
- "release_status": "stable",
- "license": "GPL_2",
- "version": "v3.4.2",
- "author": [
- "Marko Oldenburg "
- ],
- "x_fhem_maintainer": [
- "CoolTux"
- ],
- "x_fhem_maintainer_github": [
- "LeonGaultier"
- ],
- "prereqs": {
- "runtime": {
- "requires": {
- "FHEM": 5.00918799,
- "perl": 5.016,
- "Meta": 1,
- "JSON": 1,
- "Date::Parse": 0
- },
- "recommends": {
- "JSON": 0
- },
- "suggests": {
- "Cpanel::JSON::XS": 0,
- "JSON::XS": 0
- }
- }
- }
-}
-=end :application/json;q=META.json
-
-=cut
+__END__