mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
db903eb163
git-svn-id: https://svn.fhem.de/fhem/trunk@7502 2b470e98-0d58-463d-a4d8-8e2adae1ed80
750 lines
27 KiB
Perl
750 lines
27 KiB
Perl
##############################################################################
|
|
#
|
|
# 70_Jabber.pm
|
|
# An FHEM Perl module for connecting to an Jabber XMPP Server and
|
|
# send/recieve messages.
|
|
# Thanks to Predictor who had the initial idea for such a module.
|
|
#
|
|
# Copyright by BioS
|
|
#
|
|
# This file is part of fhem.
|
|
#
|
|
# Fhem 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
|
|
# (at your option) any later version.
|
|
#
|
|
# Fhem 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 fhem. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Version: 1.1 - 2014-07-28
|
|
#
|
|
# Changelog:
|
|
# v1.3 2015-01-10 Fixed DNS SRV resolving and resulting wrong to: address
|
|
# v1.2 2015-01-09 hardening XML::Stream Process() call and fix of ssl_verify
|
|
# v1.1 2014-07-28 Added UTF8 encoding / decoding to Messages
|
|
# v1.0 2014-04-10 Stable Release - Housekeeping & Add to SVN
|
|
# v0.3 2014-03-19 Fixed SetPresence() & Added extensive debugging capabilities by setting $debug to 1
|
|
# v0.2 2014-01-28 Added SSL option in addition to TLS
|
|
# v0.1 2014-01-18 Initial Release
|
|
##############################################################################
|
|
# You will need the following perl Module and all it's depencies for this to work:
|
|
# Net::Jabber
|
|
# For using the SSL features and to connect securly to a Jabber server you also need this perl Module:
|
|
# Net::SSLeay
|
|
#
|
|
# The recommended debian packages to be installed are these:
|
|
# libnet-jabber-perl libnet-xmpp-perl libxml-stream-perl libdigest-sha1-perl libauthen-sasl-perl libnet-ssleay-perl
|
|
#
|
|
# Have Phun!
|
|
#
|
|
package main;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use utf8;
|
|
use Time::HiRes qw(gettimeofday);
|
|
use Net::Jabber;
|
|
|
|
sub Jabber_Set($@);
|
|
sub Jabber_Define($$);
|
|
sub Jabber_UnDef($$);
|
|
sub Jabber_PollMessages($);
|
|
sub Jabber_CheckConnection($);
|
|
|
|
# If you want extended logging and debugging infomations
|
|
# in fhem.log please set the following value to 1
|
|
my $debug = 0;
|
|
|
|
my %sets = (
|
|
"msg" => 1,
|
|
"subscribe" => 1
|
|
);
|
|
|
|
###################################
|
|
sub
|
|
Jabber_Initialize($)
|
|
{
|
|
my ($hash) = @_;
|
|
|
|
$hash->{SetFn} = "Jabber_Set";
|
|
$hash->{DefFn} = "Jabber_Define";
|
|
$hash->{UndefFn} = "Jabber_UnDef";
|
|
$hash->{AttrFn} = "Jabber_Attr";
|
|
$hash->{AttrList} = "dummy:1,0 loglevel:0,1,2,3,4,5 OnlineStatus:available,unavailable PollTimer RecvWhitelist ResourceName ".$readingFnAttributes;
|
|
}
|
|
|
|
###################################
|
|
sub Jabber_Set($@)
|
|
{
|
|
my ($hash, $name, $cmd, @args) = @_;
|
|
|
|
if (!defined($sets{$cmd}))
|
|
{
|
|
return "Unknown argument " . $cmd . ", choose one of " . join(" ", sort keys %sets);
|
|
}
|
|
|
|
if ($cmd eq 'msg')
|
|
{
|
|
return Jabber_Set_Message($hash, @args);
|
|
}
|
|
|
|
if ($cmd eq 'subscribe')
|
|
{
|
|
return Jabber_Subcribe_To($hash, @args);
|
|
}
|
|
|
|
}
|
|
|
|
###################################
|
|
sub Jabber_Set_Message($@)
|
|
{
|
|
my ($hash,$dst,@tmpMsg) = @_;
|
|
my $message = join(" ", @tmpMsg);
|
|
utf8::decode($message);
|
|
if (Jabber_CheckConnection($hash)) {
|
|
$hash->{JabberDevice}->MessageSend(to=>$dst,
|
|
subject=>"",
|
|
body=>$message,
|
|
type=>"chat",
|
|
priority=>10);
|
|
}
|
|
}
|
|
|
|
###################################
|
|
sub Jabber_Subcribe_To($@)
|
|
{
|
|
my ($hash,$dst) = @_;
|
|
if (Jabber_CheckConnection($hash)) {
|
|
#respond with authorization so they can see our online state
|
|
$hash->{JabberDevice}->Subscription(type=>"subscribed",
|
|
to=>$dst);
|
|
#ask for authorization also so we can also see their online state (for future)
|
|
$hash->{JabberDevice}->Subscription(type=>"subscribe",
|
|
to=>$dst);
|
|
}
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
Jabber_Define($$)
|
|
{
|
|
my ($hash, $def) = @_;
|
|
my $name = $hash->{NAME};
|
|
my @args = split("[ \t]+", $def);
|
|
|
|
if (int(@args) < 8)
|
|
{
|
|
return "Invalid number of arguments: define <name> Jabber <server> <port> <username> <password> <tls> <ssl>";
|
|
}
|
|
my ($tmp1,$tmp2,$server, $port, $username, $password, $tls, $ssl) = @args;
|
|
|
|
$hash->{STATE} = 'Initialized';
|
|
|
|
#defaults:
|
|
$attr{$name}{PollTimer}=2;
|
|
$attr{$name}{ResourceName}='FHEM';
|
|
$attr{$name}{RecvWhitelist}='.*';
|
|
$attr{$name}{OnlineStatus}='available';
|
|
|
|
if(defined($server) && defined($port) && defined($username) && defined($password) && defined($tls) && defined($ssl))
|
|
{
|
|
$hash->{helper}{server} = $server;
|
|
$hash->{helper}{username} = $username;
|
|
$hash->{helper}{password} = $password;
|
|
$hash->{helper}{port} = $port;
|
|
$hash->{helper}{tls} = $tls;
|
|
$hash->{helper}{ssl} = $ssl;
|
|
if ($tls == 1 || $ssl == 1) {
|
|
if(!eval("require Net::SSLeay;")) {
|
|
$hash->{STATE} = "Disconnected (Module error)";
|
|
$hash->{CONNINFO} = "Missing perl Module Net::SSLeay for TLS or SSL connection.";
|
|
return undef;
|
|
}
|
|
}
|
|
if(!eval("require Authen::SASL;")) {
|
|
$hash->{STATE} = "Disconnected (Module error)";
|
|
$hash->{CONNINFO} = "Missing perl Module Authen::SASL for Jabber Authentication.";
|
|
return undef;
|
|
}
|
|
Jabber_CheckConnection($hash) if($init_done);
|
|
InternalTimer(gettimeofday()+$attr{$name}{PollTimer}, "Jabber_PollMessages", $hash,0);
|
|
return undef;
|
|
}
|
|
else
|
|
{
|
|
return "define not correct: define <name> Jabber <server> <port> <username> <password> <tls> <ssl>";
|
|
}
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
Jabber_UnDef($$)
|
|
{
|
|
my ($hash, $name) = @_;
|
|
RemoveInternalTimer($hash);
|
|
$hash->{JabberDevice}->Disconnect();
|
|
return undef;
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
Jabber_Attr(@)
|
|
{
|
|
my ($cmd,$name,$aName,$aVal) = @_;
|
|
my $hash = $defs{$name};
|
|
# $cmd can be "del" or "set"
|
|
# $name is device name
|
|
# aName and aVal are Attribute name and value
|
|
if ($cmd eq "set") {
|
|
if ($aName eq "OnlineStatus") {
|
|
if (defined($aVal) && defined($hash->{JabberDevice}) && $init_done) {
|
|
#Send Presence type only if we do not want to be available
|
|
if ($aVal ne "available") {
|
|
$hash->{JabberDevice}->PresenceSend(type=>$aVal);
|
|
} else {
|
|
$hash->{JabberDevice}->PresenceSend();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
###################################
|
|
sub
|
|
Jabber_PollMessages($)
|
|
{
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $connectiondied = 0;
|
|
RemoveInternalTimer($hash);
|
|
|
|
if(!$init_done) {
|
|
InternalTimer(gettimeofday()+$attr{$name}{PollTimer}, "Jabber_PollMessages", $hash,0);
|
|
return undef; # exit if FHEM is not ready yet.
|
|
}
|
|
|
|
if (Jabber_CheckConnection($hash)) {
|
|
Log 0, "$hash->{NAME} Jabber PollMessages" if $debug;
|
|
#We need to manually do what XML::Stream normally do on 'Process()' as we do not want to block it for too long.
|
|
#They only accept a multiple of second as timeout, but that is too much if we block FHEM every second a second
|
|
#If we find that there is something to do we call Process()
|
|
my $doProcess = 0;
|
|
|
|
#If there is something to read from the XMPP Server
|
|
if (defined($hash->{JabberDevice}->{STREAM}->{SELECT}->can_read(0.01))) {
|
|
$doProcess = 1;
|
|
}
|
|
|
|
#From XML::Stream - Check if a connection needs a keepalive or has been timed out.
|
|
#Again, we would block for at least one second (every 10 seconds) if we call Process() here
|
|
if ($doProcess == 0) {
|
|
|
|
#From XML::Stream - Check if a connection needs a keepalive, and send that keepalive.
|
|
foreach my $sid (keys(%{$hash->{JabberDevice}->{STREAM}->{SIDS}}))
|
|
{
|
|
next if ($sid eq "default");
|
|
next if ($sid =~ /^server/);
|
|
next if ($hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{status} == -1);
|
|
if ((time - $hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{keepalive}) > 10)
|
|
{
|
|
$hash->{JabberDevice}->{STREAM}->IgnoreActivity($sid,1);
|
|
$hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{status} = -1 if !defined($hash->{JabberDevice}->{STREAM}->Send($sid," "));
|
|
if (! $hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{status} == 1)
|
|
{
|
|
#Keep-Alive failed - we must call Process() to handle it
|
|
$doProcess = 1;
|
|
Log 0, "$hash->{NAME} Keep Alive Failed" if $debug;
|
|
}
|
|
$hash->{JabberDevice}->{STREAM}->IgnoreActivity($sid,0);
|
|
}
|
|
}
|
|
|
|
#From XML::Stream - Check if a connection timed out, if not respond, if it timed out, call Process()
|
|
foreach my $sid (keys(%{$hash->{JabberDevice}->{STREAM}->{SIDS}}))
|
|
{
|
|
next if ($sid eq "default");
|
|
next if ($sid =~ /^server/);
|
|
|
|
$hash->{JabberDevice}->{STREAM}->Respond($sid)
|
|
if (exists($hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{activitytimeout}) &&
|
|
defined($hash->{JabberDevice}->{STREAM}->GetRoot($sid)));
|
|
|
|
$doProcess = 1
|
|
if (exists($hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{activitytimeout}) &&
|
|
((time - $hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{activitytimeout}) > 10) &&
|
|
($hash->{JabberDevice}->{STREAM}->{SIDS}->{$sid}->{status} != 1));
|
|
}
|
|
}
|
|
|
|
#We do Process() - if the connection has died we reconnect.
|
|
if ($doProcess == 1) {
|
|
Log 0, "$hash->{NAME} DoProcess Call" if $debug;
|
|
|
|
#Check for previous errors in process(), before XMPP::Connection will break down FHEM
|
|
$connectiondied = 0;
|
|
if (defined($hash->{JabberDevice})) {
|
|
if (exists($hash->{JabberDevice}->{PROCESSERROR}) && ($hash->{JabberDevice}->{PROCESSERROR} == 1)) {
|
|
#XMPP::Connection would kill FHEM now.. But we try to handle it.
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Jabber connection error (Previous XMPP Process() error!)";
|
|
Log 0, "$hash->{NAME} Jabber connection error (Previous XMPP Process() error!)" if $debug;
|
|
$connectiondied = 1;
|
|
} else {
|
|
#Do Process(), if it is undef, connection is gone or some other problem...
|
|
if (!defined($hash->{JabberDevice}->Process(1))) {
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Jabber connection died";
|
|
Log 0, "$hash->{NAME} Jabber connection error (Process() is undef!)" if $debug;
|
|
$connectiondied = 1;
|
|
}
|
|
}
|
|
} else {
|
|
$connectiondied = 1;
|
|
}
|
|
|
|
if ($connectiondied == 1) {
|
|
#connection died
|
|
Log 0, "$hash->{NAME} Connection died" if $debug;
|
|
$hash->{JabberDevice} = undef;
|
|
if (Jabber_CheckConnection($hash)) {
|
|
#Send Presence type only if we do not want to be availible
|
|
if ($attr{$name}{OnlineStatus} ne "available") {
|
|
$hash->{JabberDevice}->PresenceSend(type=>$attr{$name}{OnlineStatus});
|
|
} else {
|
|
$hash->{JabberDevice}->PresenceSend();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Log 0, "$hash->{NAME} Poll End" if $debug;
|
|
}
|
|
InternalTimer(gettimeofday()+$attr{$name}{PollTimer}, "Jabber_PollMessages", $hash,0);
|
|
}
|
|
###################################
|
|
sub Jabber_CheckConnection($)
|
|
{
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
|
|
if (!defined($hash->{JabberDevice})) {
|
|
#Not defined, create a new Jabber connection
|
|
my $dev = undef;
|
|
if ($debug > 0) {
|
|
$dev = new Net::Jabber::Client(debuglevel=>2,debugfile=>"/tmp/jabberdebug.log");
|
|
} else {
|
|
$dev = new Net::Jabber::Client();
|
|
}
|
|
$hash->{JabberDevice} = $dev;
|
|
|
|
#Default to SSL = nonverify (0x00) - this has been changed in XML::Stream 1.23_04 and cause problems because you need a CA verify list.
|
|
if (defined($hash->{JabberDevice}->{STREAM}->{SIDS}->{default}->{ssl_verify})) {
|
|
$hash->{JabberDevice}->{STREAM}->{SIDS}->{default}->{ssl_verify} = 0x00;
|
|
}
|
|
|
|
#Default to to SRV lookups, ugly hack because older versions of XMPP::Connection dont call the respective value in XML::Stream..
|
|
$hash->{JabberDevice}->{STREAM}->{SIDS}->{default}->{srv} = "_xmpp-client._tcp";
|
|
|
|
#Needed for Message handling:
|
|
$hash->{JabberDevice}->SetMessageCallBacks(normal => sub { \&Jabber_INC_Message($hash,@_) }, chat => sub { \&Jabber_INC_Message($hash,@_) } );
|
|
#Needed if someone wants to subscribe to us and is on the WhiteList
|
|
$hash->{JabberDevice}->SetPresenceCallBacks(
|
|
subscribe => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
subscribed => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
available => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
unavailable => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
unsubscribe => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
unsubscribed => sub { \&Jabber_INC_Subscribe($hash,@_) },
|
|
error => sub { \&Jabber_INC_Subscribe($hash,@_) }
|
|
);
|
|
|
|
}
|
|
|
|
if (!$hash->{JabberDevice}->Connected()) {
|
|
|
|
my $connectionstatus = $hash->{JabberDevice}->Connect(
|
|
hostname=>$hash->{helper}{server},
|
|
port=>$hash->{helper}{port},
|
|
tls=>$hash->{helper}{tls},
|
|
ssl=>$hash->{helper}{ssl},
|
|
componentname=>$hash->{helper}{server}
|
|
);
|
|
|
|
if (!defined($connectionstatus)) {
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Jabber connect error ($!)";
|
|
return 0;
|
|
}
|
|
my @authresult = $hash->{JabberDevice}->AuthSend(username=>$hash->{helper}{username},
|
|
password=>$hash->{helper}{password},
|
|
resource=>$attr{$name}{ResourceName});
|
|
|
|
if (!defined($authresult[0])) {
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Jabber authentication error: Cannot Authenticate for an unknown reason. Connectionstatus is: $connectionstatus";
|
|
return 0;
|
|
}
|
|
|
|
if ($authresult[0] ne "ok") {
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Jabber authentication error: @authresult";
|
|
return 0;
|
|
}
|
|
$hash->{STATE} = "Connected";
|
|
$hash->{CONNINFO} = "Connected to $hash->{helper}{server} with username $hash->{helper}{username}";
|
|
$hash->{JabberDevice}->RosterRequest();
|
|
#Send Presence type only if we do not want to be availible
|
|
if ($attr{$name}{OnlineStatus} ne "available") {
|
|
$hash->{JabberDevice}->PresenceSend(type=>$attr{$name}{OnlineStatus});
|
|
} else {
|
|
$hash->{JabberDevice}->PresenceSend();
|
|
}
|
|
}
|
|
if (!$hash->{JabberDevice}->Connected()) {
|
|
$hash->{STATE} = "Disconnected";
|
|
$hash->{CONNINFO} = "Cannot connect for an unknown reason";
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
##########################################
|
|
sub Jabber_INC_Subscribe
|
|
{
|
|
my($hash,$session_id, $presence) = @_;
|
|
my $name = $hash->{NAME};
|
|
Log 0, "$hash->{NAME} INC_Subscribe: Recv Prsence from: " . $presence->GetFrom() . " Type: ". $presence->GetType() if $debug;
|
|
|
|
my $sender = $presence->GetFrom();
|
|
my $JID = new Net::Jabber::JID($sender);
|
|
my $senderShort = $JID->GetJID("base");
|
|
|
|
#Check the Whitelist if the sender is allowed to send us.
|
|
if ($senderShort =~ m/$attr{$name}{RecvWhitelist}/) {
|
|
Log 0, "$hash->{NAME} Regex m/$attr{$name}{RecvWhitelist}/ matched" if $debug;
|
|
|
|
if ($presence->GetType() eq "subscribe") {
|
|
#respond with authorization so they can see our online state
|
|
$hash->{JabberDevice}->Subscription(type=>"subscribed",
|
|
to=>$presence->GetFrom());
|
|
#ask for authorization also so we can also see their online state (for future)
|
|
$hash->{JabberDevice}->Subscription(type=>"subscribe",
|
|
to=>$presence->GetFrom());
|
|
}
|
|
} else {
|
|
Log 0, "$hash->{NAME} Regex m/$attr{$name}{RecvWhitelist}/ did not match" if $debug;
|
|
}
|
|
|
|
}
|
|
##########################################
|
|
sub Jabber_INC_Message {
|
|
my($hash,$session_id, $xmpp_message) = @_;
|
|
my $name = $hash->{NAME};
|
|
|
|
my $sender = $xmpp_message->GetFrom();
|
|
my $message = $xmpp_message->GetBody();
|
|
utf8::encode($message);
|
|
Log 0, "$hash->{NAME} INC_Message: $sender: $message\n" if $debug;
|
|
my $JID = new Net::Jabber::JID($sender);
|
|
my $senderShort = $JID->GetJID("base");
|
|
|
|
#Check the Whitelist if the sender is allowed to send us.
|
|
if ($senderShort =~ m/$attr{$name}{RecvWhitelist}/) {
|
|
Log 0, "$hash->{NAME} Regex m/$attr{$name}{RecvWhitelist}/ matched" if $debug;
|
|
|
|
readingsBeginUpdate($hash);
|
|
# Some IM clients send HTML, we need
|
|
# to convert it to plain text
|
|
# remove tags
|
|
$message =~ s/<(.|\n)+?>//g;
|
|
# convert "'s
|
|
$message =~ s/"/\"/g;
|
|
|
|
|
|
readingsBulkUpdate($hash,"Message","$sender: $message");
|
|
readingsBulkUpdate($hash,"LastSenderJID","$sender");
|
|
readingsBulkUpdate($hash,"LastMessage","$message");
|
|
|
|
my $response = "\n";
|
|
my $checkfordel = substr($message, 0, 3);
|
|
Log 0, "$hash->{NAME} ReadingsUpdate: $message\n" if $debug;
|
|
|
|
|
|
#$response = $message;
|
|
#if (($response eq "\n") || $response eq "") {
|
|
#$response = $response."Nothing to display for command todo $message."
|
|
#}
|
|
|
|
# $hash->{JabberDevice}->MessageSend(to=>$sender,body=>$response,type=>'chat');
|
|
readingsEndUpdate($hash, 1);
|
|
} else {
|
|
Log 0, "$hash->{NAME} Regex m/$attr{$name}{RecvWhitelist}/ did not match" if $debug;
|
|
}
|
|
}
|
|
1;
|
|
|
|
|
|
=pod
|
|
=begin html
|
|
|
|
<a name="Jabber"></a>
|
|
<h3>Jabber</h3>
|
|
<ul>
|
|
This Module allows FHEM to connect to the Jabber Network, send and receiving messages from and to a Jabber server.<br>
|
|
<br>
|
|
Jabber is another description for (XMPP) - a communications protocol for message-oriented middleware based
|
|
on XML and - depending on the server - encrypt the communications channels.<br>
|
|
For the user it is similar to other instant messaging Platforms like Facebook Chat, ICQ or Google's Hangouts
|
|
but free, Open Source and normally encrypted.<br>
|
|
<br>
|
|
You need an account on a Jabber Server, you can find free services and more information on <a href="http://www.jabber.org/">jabber.org</a><br>
|
|
Discuss the module in the <a href="http://forum.fhem.de/index.php/topic,18967.0.html">specific thread here</a>.<br>
|
|
<br>
|
|
This Module requires the following perl Modules to be installed (using SSL):<br>
|
|
<ul>
|
|
<li>Net::Jabber</li>
|
|
<li>Net::XMPP</li>
|
|
<li>Authen::SASL</li>
|
|
<li>XML::Stream</li>
|
|
<li>Net::SSLeay</li>
|
|
</ul>
|
|
<br>
|
|
<br>
|
|
<a name="JabberDefine"></a>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> Jabber <server> <port> <username> <password> <TLS> <SSL></code><br>
|
|
<br>
|
|
You have to create an account on a free Jabber server or setup your own Jabber server.<br>
|
|
<br>
|
|
Example:
|
|
<ul>
|
|
<code>define JabberClient1 Jabber jabber.org 5222 myusername mypassword 1 0</code>
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
<br>
|
|
<a name="JabberSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<li>
|
|
<code>set <name> msg <username> <msg></code>
|
|
<br>
|
|
sends a message to the specified username
|
|
<br>
|
|
Examples:
|
|
<ul>
|
|
<code>set JabberClient1 msg myname@jabber.org It is working!</code><br>
|
|
</ul>
|
|
</li>
|
|
<br>
|
|
<li>
|
|
<code>set <name> subscribe <username></code>
|
|
<br>
|
|
asks the username for authorization (not needed normally)
|
|
<br>
|
|
Example:
|
|
<ul>
|
|
<code>set JabberClient1 subscribe myname@jabber.org</code><br>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
<b>Get</b> <ul>N/A</ul><br>
|
|
<a name="JabberAttr"></a>
|
|
<b>Attributes</b>
|
|
<ul>
|
|
<a name="OnlineStatus"></a>
|
|
<li>OnlineStatus <code>available|unavailable</code><br>
|
|
Sets the online status of the client, available (online in Clients) or unavailable (offline in Clients)<br>
|
|
It is possible, on some servers, that FHEM can even recieve messages if the status is unavailable<br>
|
|
<br>
|
|
Default: <code>available</code>
|
|
</li><br>
|
|
<a name="ResourceName"></a>
|
|
<li>ResourceName <code><name></code><br>
|
|
In XMPP/Jabber you can have multiple clients connected with the same username. <br>
|
|
The resource name finally makes the Jabber-ID unique to each client.<br>
|
|
Here you can define the resource name.<br>
|
|
<br>
|
|
Default: <code>FHEM</code>
|
|
</li><br>
|
|
<a name="RecvWhitelist"></a>
|
|
<li>RecvWhitelist <code><Regex></code><br>
|
|
Only if the Regex match, the client accepts and interpret the message. Everything else will be discarded.<br>
|
|
<br>
|
|
Default: <code>.*</code><br>
|
|
Examples:<br>
|
|
<ul>
|
|
<code>myname@jabber.org</code><br>
|
|
<code>(myname1@jabber.org|myname2@xmpp.de)</code><br>
|
|
</ul>
|
|
</li><br>
|
|
<a name="PollTimer"></a>
|
|
<li>PollTimer <code><seconds></code><br>
|
|
This is the interval in seconds at which the jabber server get polled.<br>
|
|
Every interval the client checks if there are messages waiting and checks the connection to the server.<br>
|
|
Don't set it over 10 seconds, as the client could get disconnected.<br>
|
|
<br>
|
|
Default: <code>2</code>
|
|
</li><br>
|
|
</ul>
|
|
<br>
|
|
<a name="JabberEvents"></a>
|
|
<b>Generated events:</b>
|
|
<ul>
|
|
N/A
|
|
</ul>
|
|
<br>
|
|
<a name="JabberNotes"></a>
|
|
<b>Author's Notes:</b>
|
|
<ul>
|
|
<li>You can react and reply on incoming messages with a notify like this:<br>
|
|
<pre><code>define Jabber_Notify notify JabberClient1:Message.* {
|
|
my $lastsender=ReadingsVal("JabberClient1","LastSenderJID","0");
|
|
my $lastmsg=ReadingsVal("JabberClient1","LastMessage","0");
|
|
my $temperature=ReadingsVal("BU_Temperatur","temperature","0");
|
|
fhem("set JabberClient1 msg ". $lastsender . " Temp: ".$temperature);
|
|
}
|
|
</code></pre>
|
|
</li>
|
|
</ul>
|
|
</ul>
|
|
=end html
|
|
=begin html_DE
|
|
|
|
<a name="Jabber"></a>
|
|
<h3>Jabber</h3>
|
|
<ul>
|
|
Dieses Modul verbindet sich mit dem Jabber Netzwerk, sendet und empfängt Nachrichten von und zu einem Jabber Server.<br>
|
|
<br>
|
|
Jabber ist eine andere Beschreibung für "XMPP", ein Kommunikationsprotokoll für Nachrichtenorientierte "middleware", basierend
|
|
auf XML.<br>
|
|
Fester bestandteil des Protokolls ist die Verschlüsselung zwischen Client und Server.<br>
|
|
Für den Benutzer ist es ähnlich anderer Chat-Plattformen wie zum Beispiel dem facebook Chat, ICQ oder Google Hangouts -
|
|
jedoch frei Verfügbar, open Source und normalerweise Verschlüsselt (was Serverabhängig ist).<br>
|
|
<br>
|
|
Für dieses Modul brauchst du einen Account auf einem Jabber Server. Kostenlose accounts und Server findet man unter <a href="http://www.jabber.org/">jabber.org</a><br>
|
|
Diskussionen zu diesem Modul findet man im <a href="http://forum.fhem.de/index.php/topic,18967.0.html">FHEM Forum hier</a>.<br>
|
|
<br>
|
|
Dieses Modul benötigt die folgenden Perl Module (inkl. SSL Möglichkeit)<br>
|
|
<ul>
|
|
<li>Net::Jabber</li>
|
|
<li>Net::XMPP</li>
|
|
<li>Authen::SASL</li>
|
|
<li>XML::Stream</li>
|
|
<li>Net::SSLeay</li>
|
|
</ul>
|
|
<br>
|
|
<br>
|
|
<a name="JabberDefine"></a>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> Jabber <server> <port> <username> <password> <TLS> <SSL></code><br>
|
|
<br>
|
|
Du benötigst natürlich echte Accountdaten.<br>
|
|
<br>
|
|
Beispiel:
|
|
<ul>
|
|
<code>define JabberClient1 Jabber jabber.org 5222 myusername mypassword 1 0</code>
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
<br>
|
|
<a name="JabberSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<li>
|
|
<code>set <name> msg <username> <msg></code>
|
|
<br>
|
|
Sendet eine Nachricht "msg" an den Jabberuser "username"
|
|
<br>
|
|
Beispiel:
|
|
<ul>
|
|
<code>set JabberClient1 msg myname@jabber.org It is working!</code><br>
|
|
</ul>
|
|
</li>
|
|
<br>
|
|
<li>
|
|
<code>set <name> subscribe <username></code>
|
|
<br>
|
|
Frägt eine Authorisierung beim "username" an (normalerweise wird das nicht benötigt)
|
|
<br>
|
|
Beispiel:
|
|
<ul>
|
|
<code>set JabberClient1 subscribe myname@jabber.org</code><br>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
<b>Get</b> <ul>N/A</ul><br>
|
|
<a name="JabberAttr"></a>
|
|
<b>Attribute</b>
|
|
<ul>
|
|
<a name="OnlineStatus"></a>
|
|
<li>OnlineStatus <code>available|unavailable</code><br>
|
|
Setzt den Online-status, ob der Client anderen gegenüber Online ist (available) oder Offline erscheint (unavailable)<br>
|
|
Es ist möglich dass einige Server eingehende Nachrichten trotzdem FHEM zustellen obwohl er "unavailable" ist<br>
|
|
<br>
|
|
Standard: <code>available</code>
|
|
</li><br>
|
|
<a name="ResourceName"></a>
|
|
<li>ResourceName <code><name></code><br>
|
|
In der Jabber-Welt kann ein Client mit einem Usernamen öfter mit einem Server verbunden sein (z.b. Handy, Computer, FHEM). <br>
|
|
Der "resource name" ergibt die finale Jabber-ID und macht die verschiedenen Verbindungen einzigartig (z.B. bios@jabber.org/FHEM).<br>
|
|
Hier kannst du den "resource name" setzen.<br>
|
|
<br>
|
|
Standard: <code>FHEM</code>
|
|
</li><br>
|
|
<a name="RecvWhitelist"></a>
|
|
<li>RecvWhitelist <code><Regex></code><br>
|
|
Nur wenn die Jabber-ID einer empfangenen Nachricht auf diese Regex zutrifft, akzeptiert FHEM die Nachricht und gibt sie an Notifys weiter. Alles andere wird verworfen.<br>
|
|
<br>
|
|
Standard: <code>.*</code><br>
|
|
Beispiele:<br>
|
|
<ul>
|
|
<code>myname@jabber.org</code><br>
|
|
<code>(myname1@jabber.org|myname2@xmpp.de)</code><br>
|
|
</ul>
|
|
</li><br>
|
|
<a name="PollTimer"></a>
|
|
<li>PollTimer <code><seconds></code><br>
|
|
Dies ist der Intervall in der überprüft wird ob neue Nachrichten zur Verarbeitung beim Jabber Server anstehen.<br>
|
|
Ebenfalls wird hiermit die Verbindung zum Server überprüft (Timeouts, DSL Disconnects etc.).<br>
|
|
Setze es nicht über 10 Sekunden, die Verbindung kann sonst die ganze Zeit getrennt werden, Sie wird zwar wieder aufgebaut, aber nach 10 Sekunden brechen die meisten Server die Verbindung automatisch ab.<br>
|
|
<br>
|
|
Standard: <code>2</code>
|
|
</li><br>
|
|
</ul>
|
|
<br>
|
|
<a name="JabberEvents"></a>
|
|
<b>Generierte events:</b>
|
|
<ul>
|
|
N/A
|
|
</ul>
|
|
<br>
|
|
<a name="JabberNotes"></a>
|
|
<b>Notizen des Entwicklers:</b>
|
|
<ul>
|
|
<li>Mit folgendem Notify-Beispiel kannst du auf eingehende Nachrichten reagieren, dieses Beispiel schickt das Reading "Temperatur" des Sensors "BU_Temperatur" bei jeder ankommenden Nachricht an den Sender zurück:<br>
|
|
<pre><code>define Jabber_Notify notify JabberClient1:Message.* {
|
|
my $lastsender=ReadingsVal("JabberClient1","LastSenderJID","0");
|
|
my $lastmsg=ReadingsVal("JabberClient1","LastMessage","0");
|
|
my $temperature=ReadingsVal("BU_Temperatur","temperature","0");
|
|
fhem("set JabberClient1 msg ". $lastsender . " Temp: ".$temperature);
|
|
}
|
|
</code></pre>
|
|
</li>
|
|
</ul>
|
|
</ul>
|
|
=end html_DE
|
|
=cut
|