2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-01 15:44:52 +00:00

49_SSCam: contrib 8.10.0

git-svn-id: https://svn.fhem.de/fhem/trunk@18572 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2019-02-12 20:26:31 +00:00
parent bf4e21ed62
commit 63292badaa

View File

@ -1,5 +1,5 @@
######################################################################################################################## ########################################################################################################################
# $Id: 49_SSCam.pm 18452 2019-01-29 22:39:55Z DS_Starter $ # $Id: 49_SSCam.pm 18538 2019-02-09 07:49:49Z DS_Starter $
######################################################################################################################### #########################################################################################################################
# 49_SSCam.pm # 49_SSCam.pm
# #
@ -47,6 +47,7 @@ use Encode;
# Versions History intern # Versions History intern
our %SSCam_vNotesIntern = ( our %SSCam_vNotesIntern = (
"8.10.0" => "12.02.2019 send recordings integrated by telegram, a lot of internal changes for send telegrams ",
"8.9.2" => "05.02.2019 sub SSCam_sendTelegram changed ", "8.9.2" => "05.02.2019 sub SSCam_sendTelegram changed ",
"8.9.1" => "05.02.2019 sub SSCam_snaplimsize changed ", "8.9.1" => "05.02.2019 sub SSCam_snaplimsize changed ",
"8.9.0" => "05.02.2019 new streaming device type \"lastsnap\" ", "8.9.0" => "05.02.2019 new streaming device type \"lastsnap\" ",
@ -129,6 +130,7 @@ our %SSCam_vNotesIntern = (
# Versions History extern # Versions History extern
our %SSCam_vNotesExtern = ( our %SSCam_vNotesExtern = (
"8.10.0" => "12.02.2019 Possibility of send recordings by telegram is integrated as well as sending snapshots ",
"8.9.0" => "05.02.2019 A new streaming device type \"lastsnap\" was implemented. You can create such device with \"set ... createStreamDev lastsnap\". ". "8.9.0" => "05.02.2019 A new streaming device type \"lastsnap\" was implemented. You can create such device with \"set ... createStreamDev lastsnap\". ".
"This streaming device shows the newest snapshot which was taken. ", "This streaming device shows the newest snapshot which was taken. ",
"8.8.0" => "01.02.2019 Snapshots can now be sent by telegramBot ", "8.8.0" => "01.02.2019 Snapshots can now be sent by telegramBot ",
@ -320,8 +322,8 @@ our %SSCam_ttips_de = (
); );
# Standardvariablen und Forward-Deklaration # Standardvariablen und Forward-Deklaration
my $SSCam_slim = 3; # default Anzahl der abzurufenden Schnappschüsse mit snapGallery my $SSCam_slim = 3; # default Anzahl der abzurufenden Schnappschüsse mit snapGallery
my $SSCAM_snum = "1,2,3,4,5,6,7,8,9,10"; # mögliche Anzahl der abzurufenden Schnappschüsse mit snapGallery my $SSCAM_snum = "1,2,3,4,5,6,7,8,9,10"; # mögliche Anzahl der abzurufenden Schnappschüsse mit snapGallery
use vars qw($FW_ME); # webname (default is fhem), used by 97_GROUP/weblink use vars qw($FW_ME); # webname (default is fhem), used by 97_GROUP/weblink
use vars qw($FW_subdir); # Sub-path in URL, used by FLOORPLAN/weblink use vars qw($FW_subdir); # Sub-path in URL, used by FLOORPLAN/weblink
@ -377,6 +379,7 @@ sub SSCam_Initialize($) {
"pollnologging:1,0 ". "pollnologging:1,0 ".
"debugactivetoken:1,0 ". "debugactivetoken:1,0 ".
"recEmailTxt ". "recEmailTxt ".
"recTelegramTxt ".
"rectime ". "rectime ".
"recextend:1,0 ". "recextend:1,0 ".
"noQuotesForSID:1,0 ". "noQuotesForSID:1,0 ".
@ -812,12 +815,26 @@ sub SSCam_Set($@) {
$hash->{HELPER}{SMTPRECMSG} = $emtxt; $hash->{HELPER}{SMTPRECMSG} = $emtxt;
} }
my $teletxt = AttrVal($name, "recTelegramTxt", "");
my $bt = join(" ",@a);
if($bt =~ /recTelegramTxt:/) {
$bt =~ m/.*recTelegramTxt:"(.*)".*/i;
$teletxt = $1;
}
if ($teletxt) {
# Recording soll nach Erstellung per TelegramBot versendet werden
# Format $teletxt muss sein: recTelegramTxt:"tbot => <teleBot Device>, peers => <peer1 peer2 ..>, subject => <Beschreibungstext>"
$hash->{HELPER}{TELERECMSG} = $teletxt;
}
SSCam_camstartrec($hash); SSCam_camstartrec($hash);
} elsif ($opt eq "off" && SSCam_IsModelCam($hash)) { } elsif ($opt eq "off" && SSCam_IsModelCam($hash)) {
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
my $emtxt = $hash->{HELPER}{SMTPRECMSG}?delete $hash->{HELPER}{SMTPRECMSG}:""; my $emtxt = $hash->{HELPER}{SMTPRECMSG}?delete $hash->{HELPER}{SMTPRECMSG}:"";
SSCam_camstoprec("$name:$emtxt"); my $teletxt = $hash->{HELPER}{TELERECMSG}?delete $hash->{HELPER}{TELERECMSG}:"";
SSCam_camstoprec("$name:$emtxt:$teletxt");
} elsif ($opt eq "snap" && SSCam_IsModelCam($hash)) { } elsif ($opt eq "snap" && SSCam_IsModelCam($hash)) {
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
@ -1827,8 +1844,8 @@ sub SSCam_initonboot ($) {
# check ob alle Recordings = "Stop" nach Reboot -> sonst stoppen # check ob alle Recordings = "Stop" nach Reboot -> sonst stoppen
if (ReadingsVal($hash->{NAME}, "Record", "Stop") eq "Start") { if (ReadingsVal($hash->{NAME}, "Record", "Stop") eq "Start") {
Log3($name, 2, "$name - Recording of $hash->{CAMNAME} seems to be still active after FHEM restart - try to stop it now"); Log3($name, 2, "$name - Recording of $hash->{CAMNAME} seems to be still active after FHEM restart - try to stop it now");
my $emtxt = ""; my ($emtxt,$teletxt) = ("","");
SSCam_camstoprec("$name:$emtxt"); SSCam_camstoprec("$name:$emtxt:$teletxt");
} }
# Konfiguration der Synology Surveillance Station abrufen # Konfiguration der Synology Surveillance Station abrufen
@ -2129,10 +2146,10 @@ sub SSCam_camstartrec ($) {
# Kamera Aufnahme stoppen # Kamera Aufnahme stoppen
############################################################################### ###############################################################################
sub SSCam_camstoprec ($) { sub SSCam_camstoprec ($) {
my ($str) = @_; my ($str) = @_;
my ($name,$emtxt) = split(":",$str); my ($name,$emtxt,$teletxt) = split(":",$str);
my $hash = $defs{$name}; my $hash = $defs{$name};
my $camname = $hash->{CAMNAME}; my $camname = $hash->{CAMNAME};
my $errorcode; my $errorcode;
my $error; my $error;
@ -2167,16 +2184,18 @@ sub SSCam_camstoprec ($) {
if ($hash->{HELPER}{ACTIVE} eq "off") { if ($hash->{HELPER}{ACTIVE} eq "off") {
$hash->{OPMODE} = "Stop"; $hash->{OPMODE} = "Stop";
$hash->{HELPER}{LOGINRETRIES} = 0; $hash->{HELPER}{LOGINRETRIES} = 0;
if($emtxt) { if($emtxt || $teletxt) {
$hash->{HELPER}{CANSENDREC} = 1; # Versand Aufnahme soll erfolgen $hash->{HELPER}{CANSENDREC} = 1 if($emtxt); # Versand Aufnahme soll per Email erfolgen
$hash->{HELPER}{SMTPRECMSG} = $emtxt; # Text für Email-Versand $hash->{HELPER}{CANTELEREC} = 1 if($teletxt); # Versand Aufnahme soll per TelegramBot erfolgen
$hash->{HELPER}{SMTPRECMSG} = $emtxt if($emtxt); # Text für Email-Versand
$hash->{HELPER}{TELERECMSG} = $teletxt if($teletxt); # Text für Telegram-Versand
} }
SSCam_setActiveToken($hash); SSCam_setActiveToken($hash);
SSCam_getapisites($hash); SSCam_getapisites($hash);
} else { } else {
InternalTimer(gettimeofday()+0.3, "SSCam_camstoprec", "$name:$emtxt", 0); InternalTimer(gettimeofday()+0.3, "SSCam_camstoprec", "$name:$emtxt:$teletxt", 0);
} }
} }
@ -4796,7 +4815,6 @@ sub SSCam_camop_parse ($) {
($hash,$success,$myjson) = SSCam_evaljson($hash,$myjson); ($hash,$success,$myjson) = SSCam_evaljson($hash,$myjson);
unless ($success) { unless ($success) {
Log3($name, 4, "$name - Data returned: ".$myjson); Log3($name, 4, "$name - Data returned: ".$myjson);
SSCam_delActiveToken($hash); SSCam_delActiveToken($hash);
return; return;
} }
@ -4844,9 +4862,10 @@ sub SSCam_camop_parse ($) {
if ($rectime != 0) { if ($rectime != 0) {
# Stop der Aufnahme nach Ablauf $rectime, wenn rectime = 0 -> endlose Aufnahme # Stop der Aufnahme nach Ablauf $rectime, wenn rectime = 0 -> endlose Aufnahme
my $emtxt = $hash->{HELPER}{SMTPRECMSG}?$hash->{HELPER}{SMTPRECMSG}:""; my $emtxt = $hash->{HELPER}{SMTPRECMSG}?$hash->{HELPER}{SMTPRECMSG}:"";
my $teletxt = $hash->{HELPER}{TELERECMSG}?$hash->{HELPER}{TELERECMSG}:"";
RemoveInternalTimer($hash, "SSCam_camstoprec"); RemoveInternalTimer($hash, "SSCam_camstoprec");
InternalTimer(gettimeofday()+$rectime, "SSCam_camstoprec", "$name:$emtxt"); InternalTimer(gettimeofday()+$rectime, "SSCam_camstoprec", "$name:$emtxt:$teletxt");
} }
SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event
@ -4893,7 +4912,7 @@ sub SSCam_camop_parse ($) {
$sendrecs{$sn}{".imageData"} = $myjson; $sendrecs{$sn}{".imageData"} = $myjson;
Log3($name,4, "$name - Snap '$sn' added to send recording hash: ID => $sendrecs{$sn}{recid}, File => $sendrecs{$sn}{fileName}, Created => $sendrecs{$sn}{createdTm}"); Log3($name,4, "$name - Snap '$sn' added to send recording hash: ID => $sendrecs{$sn}{recid}, File => $sendrecs{$sn}{fileName}, Created => $sendrecs{$sn}{createdTm}");
# prüfen ob Recording als Email versendet werden soll # prüfen ob Recording als Email / Telegram versendet werden soll
SSCam_prepareSendData ($hash, $OpMode, \%sendrecs); SSCam_prepareSendData ($hash, $OpMode, \%sendrecs);
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
@ -5884,7 +5903,7 @@ sub SSCam_camop_parse ($) {
Log3($name, $verbose, "$name - Query eventlist of camera $camname retrieved"); Log3($name, $verbose, "$name - Query eventlist of camera $camname retrieved");
# Versand Aufnahme initiieren # Versand Aufnahme initiieren
if($hash->{HELPER}{CANSENDREC}) { if($hash->{HELPER}{CANSENDREC} || $hash->{HELPER}{CANTELEREC}) {
SSCam_getrec($hash); SSCam_getrec($hash);
} }
@ -7631,7 +7650,7 @@ sub SSCam_prepareSendData ($$;$) {
$smtpsslport = AttrVal($name,"smtpSSLPort",0); $smtpsslport = AttrVal($name,"smtpSSLPort",0);
} }
### Bilddaten als Email versenden wenn $hash->{HELPER}{CANSENDSNAP} definiert ist ### Schnappschüsse als Email versenden wenn $hash->{HELPER}{CANSENDSNAP} definiert ist
if($OpMode =~ /^getsnap/ && $hash->{HELPER}{CANSENDSNAP}) { if($OpMode =~ /^getsnap/ && $hash->{HELPER}{CANSENDSNAP}) {
delete $hash->{HELPER}{CANSENDSNAP}; delete $hash->{HELPER}{CANSENDSNAP};
my $mt = delete $hash->{HELPER}{SMTPMSG}; my $mt = delete $hash->{HELPER}{SMTPMSG};
@ -7671,7 +7690,7 @@ sub SSCam_prepareSendData ($$;$) {
); );
} }
### Recordings als Email versenden wenn $hash->{HELPER}{CANSENDREC} definiert ist ### Aufnahmen als Email versenden wenn $hash->{HELPER}{CANSENDREC} definiert ist
if($OpMode =~ /^GetRec/ && $hash->{HELPER}{CANSENDREC}) { if($OpMode =~ /^GetRec/ && $hash->{HELPER}{CANSENDREC}) {
delete $hash->{HELPER}{CANSENDREC}; delete $hash->{HELPER}{CANSENDREC};
my $mt = delete $hash->{HELPER}{SMTPRECMSG}; my $mt = delete $hash->{HELPER}{SMTPRECMSG};
@ -7708,7 +7727,7 @@ sub SSCam_prepareSendData ($$;$) {
); );
} }
### Bilddaten mit Telegram versenden ### Schnappschüsse mit Telegram versenden
if($OpMode =~ /^getsnap/ && $hash->{HELPER}{CANTELESNAP}) { if($OpMode =~ /^getsnap/ && $hash->{HELPER}{CANTELESNAP}) {
# snapTelegramTxt aus $hash->{HELPER}{TELEMSG} # snapTelegramTxt aus $hash->{HELPER}{TELEMSG}
# Format in $hash->{HELPER}{TELEMSG} muss sein: tbot => <teleBot Device>, peers => <peer1 peer2 ..>, subject => <Beschreibungstext> # Format in $hash->{HELPER}{TELEMSG} muss sein: tbot => <teleBot Device>, peers => <peer1 peer2 ..>, subject => <Beschreibungstext>
@ -7753,6 +7772,47 @@ sub SSCam_prepareSendData ($$;$) {
); );
} }
### Aufnahmen mit Telegram versenden
if($OpMode =~ /^GetRec/ && $hash->{HELPER}{CANTELEREC}) {
# recTelegramTxt aus $hash->{HELPER}{TELERECMSG}
# Format in $hash->{HELPER}{TELEMSG} muss sein: tbot => <teleBot Device>, peers => <peer1 peer2 ..>, subject => <Beschreibungstext>
delete $hash->{HELPER}{CANTELEREC};
my $mt = delete $hash->{HELPER}{TELERECMSG};
$mt =~ s/['"]//g;
my($telebot,$peers,$subj) = split(",", $mt, 3);
my($tbotk,$tbott) = split("=>", $telebot) if($telebot);
my($peerk,$peert) = split("=>", $peers) if($peers);
my($subjk,$subjt) = split("=>", $subj) if($subj);
$tbotk = SSCam_trim($tbotk) if($tbotk);
$tbott = SSCam_trim($tbott) if($tbott);
$peerk = SSCam_trim($peerk) if($peerk);
$peert = SSCam_trim($peert) if($peert);
$subjk = SSCam_trim($subjk) if($subjk);
if($subjt) {
$subjt = SSCam_trim($subjt);
$subjt =~ s/\$CAM/$calias/g;
$subjt =~ s/\$DATE/$date/g;
$subjt =~ s/\$TIME/$time/g;
}
my %telemsg = ();
$telemsg{$tbotk} = "$tbott" if($tbott);
$telemsg{$peerk} = "$peert" if($peert);
$telemsg{$subjk} = "$subjt" if($subjt);
$vdat = $data;
$ret = SSCam_sendTelegram($hash, {'subject' => $telemsg{subject},
'vdat' => $vdat,
'opmode' => $OpMode,
'telebot' => $telemsg{$tbotk},
'peers' => $telemsg{$peerk},
'MediaStream' => '-30', # Code für MediaStream im TelegramBot (png/jpg = -1)
}
);
}
return; return;
} }
@ -7775,11 +7835,11 @@ sub SSCam_sendTelegram ($$) {
'part2type' => { 'default'=>'', 'required'=>0, 'set'=>1}, 'part2type' => { 'default'=>'', 'required'=>0, 'set'=>1},
'sdat' => { 'default'=>'', 'required'=>0, 'set'=>1}, # (Hash)Daten base64 codiert, wenn gesetzt muss 'part2type' auf 'image/jpeg' gesetzt sein 'sdat' => { 'default'=>'', 'required'=>0, 'set'=>1}, # (Hash)Daten base64 codiert, wenn gesetzt muss 'part2type' auf 'image/jpeg' gesetzt sein
'image' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Daten als File, wenn gesetzt muss 'part2type' auf 'image/jpeg' gesetzt sein 'image' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Daten als File, wenn gesetzt muss 'part2type' auf 'image/jpeg' gesetzt sein
'fname' => { 'default'=>'image.jpg', 'required'=>0, 'set'=>1}, # Filename für "image" 'fname' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Filename für "image"
'lsnaptime' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Zeitstempel der Bilddaten 'lsnaptime' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Zeitstempel der Bilddaten
'opmode' => { 'default'=>'', 'required'=>1, 'set'=>1}, # OpMode muss gesetzt sein 'opmode' => { 'default'=>'', 'required'=>1, 'set'=>1}, # OpMode muss gesetzt sein
'tac' => { 'default'=>'', 'required'=>0, 'set'=>1}, # übermittelter Transaktionscode der ausgewerteten Transaktion 'tac' => { 'default'=>'', 'required'=>0, 'set'=>1}, # übermittelter Transaktionscode der ausgewerteten Transaktion
'vdat' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Videodaten, wenn gesetzt muss 'part2type' auf 'video/mpeg' gesetzt sein 'vdat' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Hashref der Videodaten
'telebot' => { 'default'=>'', 'required'=>1, 'set'=>1}, # TelegramBot-Device welches zum Senden verwendet werden soll 'telebot' => { 'default'=>'', 'required'=>1, 'set'=>1}, # TelegramBot-Device welches zum Senden verwendet werden soll
'peers' => { 'default'=>'', 'required'=>0, 'set'=>1}, # TelegramBot Peers 'peers' => { 'default'=>'', 'required'=>0, 'set'=>1}, # TelegramBot Peers
'MediaStream' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Code für MediaStream im TelegramBot (png/jpg = -1) 'MediaStream' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Code für MediaStream im TelegramBot (png/jpg = -1)
@ -7790,11 +7850,11 @@ sub SSCam_sendTelegram ($$) {
$params{$key} = AttrVal($name, $SSCam_teleparams{$key}->{attr}, $SSCam_teleparams{$key}->{default}) $params{$key} = AttrVal($name, $SSCam_teleparams{$key}->{attr}, $SSCam_teleparams{$key}->{default})
if(exists $SSCam_teleparams{$key}->{attr}); if(exists $SSCam_teleparams{$key}->{attr});
if($SSCam_teleparams{$key}->{set}) { if($SSCam_teleparams{$key}->{set}) {
$params{$key} = $extparamref->{$key} if (exists $extparamref->{$key}); $params{$key} = $extparamref->{$key} if(exists $extparamref->{$key});
$params{$key} = $SSCam_teleparams{$key}->{default} if (!$extparamref->{$key} && !$SSCam_teleparams{$key}->{attr}); $params{$key} = $SSCam_teleparams{$key}->{default} if (!$extparamref->{$key} && !$SSCam_teleparams{$key}->{attr});
} }
Log3($name, 4, "$name - param $key is now \"".$params{$key}."\" ") if($key !~ /sdat/); Log3($name, 4, "$name - param $key is now \"".$params{$key}."\" ") if($key !~ /[sv]dat/);
Log3($name, 4, "$name - param $key is set") if($key =~ /sdat/ && $params{$key} ne ''); Log3($name, 4, "$name - param $key is set") if($key =~ /[sv]dat/ && $params{$key} ne '');
} }
$params{name} = $name; $params{name} = $name;
@ -7815,6 +7875,7 @@ sub SSCam_sendTelegram ($$) {
my $telebot = $params{telebot}; my $telebot = $params{telebot};
my $peers = $params{peers}; my $peers = $params{peers};
my $sdat = $params{sdat}; # Hash von Imagedaten base64 codiert my $sdat = $params{sdat}; # Hash von Imagedaten base64 codiert
my $vdat = $params{vdat}; # Hashref der Videodaten
if(!$defs{$telebot}) { if(!$defs{$telebot}) {
$ret = "No TelegramBot device \"$telebot\" available"; $ret = "No TelegramBot device \"$telebot\" available";
@ -7835,16 +7896,14 @@ sub SSCam_sendTelegram ($$) {
} }
} }
no strict "refs"; no strict "refs";
my ($msg,$subject,$MediaStream); my ($msg,$subject,$MediaStream,$fname);
if($sdat) { if($sdat) {
### Images liegen in einem Hash (Ref in $sdat) base64-codiert vor ### Images liegen in einem Hash (Ref in $sdat) base64-codiert vor
my @as = sort{$b<=>$a}keys%{$sdat}; my @as = sort{$b<=>$a}keys%{$sdat};
foreach my $key (@as) { foreach my $key (@as) {
($msg,$subject,$MediaStream) = SSCam_cmdSendTelegram($name,$key); ($msg,$subject,$MediaStream,$fname) = SSCam_extractForTelegram($name,$key);
$ret = TelegramBot_SendIt( $defs{$telebot}, $peers, $msg, $subject, $MediaStream, undef, "" ); $ret = SSCam_TBotSendIt($defs{$telebot}, $name, $fname, $peers, $msg, $subject, $MediaStream, undef, "");
if($ret) { if($ret) {
readingsSingleUpdate($hash, "sendTeleState", $ret, 1); readingsSingleUpdate($hash, "sendTeleState", $ret, 1);
Log3($name, 2, "$name - ERROR: $ret"); Log3($name, 2, "$name - ERROR: $ret");
@ -7855,6 +7914,22 @@ sub SSCam_sendTelegram ($$) {
} }
} }
} }
if($vdat) {
### Aufnahmen liegen in einem Hash-Ref in $vdat vor
my $key = 0;
($msg,$subject,$MediaStream,$fname) = SSCam_extractForTelegram($name,$key);
$ret = SSCam_TBotSendIt($defs{$telebot}, $name, $fname, $peers, $msg, $subject, $MediaStream, undef, "");
if($ret) {
readingsSingleUpdate($hash, "sendTeleState", $ret, 1);
Log3($name, 2, "$name - ERROR: $ret");
} else {
$ret = "Telegram message successfully sent to \"$peers\" by \"$telebot\" ";
readingsSingleUpdate($hash, "sendTeleState", $ret, 1);
Log3($name, 3, "$name - $ret");
}
}
use strict "refs"; use strict "refs";
%params = (); # erstellten Versandhash löschen %params = (); # erstellten Versandhash löschen
@ -7864,23 +7939,337 @@ return;
#################################################################################################### ####################################################################################################
# Bilddaten extrahieren für Telegram Versand # Bilddaten extrahieren für Telegram Versand
#################################################################################################### ####################################################################################################
sub SSCam_cmdSendTelegram($$) { sub SSCam_extractForTelegram($$) {
my ($name,$key) = @_; my ($name,$key) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
my $paref = $hash->{HELPER}{PAREF}; my $paref = $hash->{HELPER}{PAREF};
my $subject = $paref->{subject}; my $subject = $paref->{subject};
my $MediaStream = $paref->{MediaStream}; my $MediaStream = $paref->{MediaStream};
my $sdat = $paref->{sdat}; # Hash von Imagedaten base64 codiert
my $vdat = $paref->{vdat}; # Hashref der Videodaten
my ($data,$fname,$ct);
my $ct = $paref->{sdat}{$key}{createdTm}; if($sdat) {
my $img = $paref->{sdat}{$key}{".imageData"}; $ct = $paref->{sdat}{$key}{createdTm};
my $fname = SSCam_trim($paref->{sdat}{$key}{fileName}); my $img = $paref->{sdat}{$key}{".imageData"};
my $decoded = MIME::Base64::decode_base64($img); $fname = SSCam_trim($paref->{sdat}{$key}{fileName});
Log3($name, 4, "$name - image data were decoded for TelegramBot prepare"); $data = MIME::Base64::decode_base64($img);
Log3($name, 4, "$name - image data decoded for TelegramBot prepare");
}
if($vdat) {
$ct = $paref->{vdat}{$key}{createdTm};
$data = $paref->{vdat}{$key}{".imageData"};
$fname = SSCam_trim($paref->{vdat}{$key}{fileName});
}
$subject =~ s/\$FILE/$fname/g; $subject =~ s/\$FILE/$fname/g;
$subject =~ s/\$CTIME/$ct/g; $subject =~ s/\$CTIME/$ct/g;
return ($decoded,$subject,$MediaStream); return ($data,$subject,$MediaStream,$fname);
}
####################################################################################################
# Telegram Send Foto & Aufnahmen
# Adaption der Sub "SendIt" aus TelegramBot
# $hash = Hash des verwendeten TelegramBot-Devices !
# $isMedia = -1 wenn Foto, -30 wenn Aufnahme
####################################################################################################
sub SSCam_TBotSendIt($$$$$$$;$$$) {
my ($hash, $camname, $fname, @args) = @_;
my ($peers, $msg, $addPar, $isMedia, $replyid, $options, $retryCount) = @args;
my $name = $hash->{NAME};
my $SSCam_TBotHeader = "agent: TelegramBot/1.0\r\nUser-Agent: TelegramBot/1.0\r\nAccept: application/json\r\nAccept-Charset: utf-8";
my $SSCam_TBotArgRetrycnt = 6;
$retryCount = 0 if (!defined($retryCount));
$options = "" if (!defined($options));
# increase retrycount for next try
$args[$SSCam_TBotArgRetrycnt] = $retryCount+1;
Log3($camname, 5, "$camname - SSCam_TBotSendIt: called ");
# ignore all sends if disabled
return if (AttrVal($name,"disable",0));
# ensure sentQueue exists
$hash->{sentQueue} = [] if (!defined($hash->{sentQueue}));
if ((defined( $hash->{sentMsgResult})) && ($hash->{sentMsgResult} =~ /^WAITING/) && ($retryCount == 0) ){
# add to queue
Log3($camname, 4, "$camname - SSCam_TBotSendIt: add send to queue :$peers: -:".
TelegramBot_MsgForLog($msg, ($isMedia<0)).": - :".(defined($addPar)?$addPar:"<undef>").":");
push(@{$hash->{sentQueue}}, \@args);
return;
}
my $ret;
$hash->{sentMsgResult} = "WAITING";
$hash->{sentMsgResult} .= " retry $retryCount" if ($retryCount>0);
$hash->{sentMsgId} = "";
my $peer;
($peer,$peers) = split(" ", $peers, 2);
# handle addtl peers specified (will be queued since WAITING is set already)
if (defined( $peers )) {
# remove msgid from options and also replyid reset
my $sepoptions = $options;
$sepoptions =~ s/-msgid-//;
SSCam_TBotSendIt($hash,$camname,$fname,$peers,$msg,$addPar,$isMedia,undef,$sepoptions);
}
Log3($camname, 5, "$camname - SSCam_TBotSendIt: try to send message to :$peer: -:".
TelegramBot_MsgForLog($msg, ($isMedia<0) ).": - add :".(defined($addPar)?$addPar:"<undef>").
": - replyid :".(defined($replyid)?$replyid:"<undef>").
":".": options :".$options.":");
# trim and convert spaces in peer to underline
$peer = 0 if ( ! $peer );
my $peer2 = (!$peer)?$peer:TelegramBot_GetIdForPeer($hash, $peer);
if (!defined($peer2)) {
$ret = "FAILED peer not found :$peer:";
$peer2 = "";
}
$hash->{sentMsgPeer} = TelegramBot_GetFullnameForContact($hash,$peer2);
$hash->{sentMsgPeerId} = $peer2;
$hash->{sentMsgOptions} = $options;
# init param hash
$hash->{HU_DO_PARAMS}->{hash} = $hash;
$hash->{HU_DO_PARAMS}->{header} = $SSCam_TBotHeader;
delete( $hash->{HU_DO_PARAMS}->{args} );
delete( $hash->{HU_DO_PARAMS}->{boundary} );
my $timeout = AttrVal($name,'cmdTimeout',30);
$hash->{HU_DO_PARAMS}->{timeout} = $timeout;
$hash->{HU_DO_PARAMS}->{loglevel} = 4;
# Start Versand
if (!defined($ret)) {
# add chat / user id (no file) --> this will also do init
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "chat_id", undef, $peer2, 0 ) if ( $peer );
if (abs($isMedia) == 1) {
# Foto send
$hash->{sentMsgText} = "Image: ".TelegramBot_MsgForLog($msg,($isMedia<0)).((defined($addPar))?" - ".$addPar:"");
$hash->{HU_DO_PARAMS}->{url} = TelegramBot_getBaseURL($hash)."sendPhoto";
# add caption
if (defined($addPar)) {
$addPar =~ s/(?<![\\])\\n/\x0A/g;
$addPar =~ s/(?<![\\])\\t/\x09/g;
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "caption", undef, $addPar, 0 ) if (!defined($ret));
$addPar = undef;
}
# add msg or file or stream
Log3($camname, 4, "$camname - SSCam_TBotSendIt: Filename for image file :".
TelegramBot_MsgForLog($msg, ($isMedia<0) ).":");
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "photo", undef, $msg, $isMedia) if(!defined($ret));
} elsif ( abs($isMedia) == 30 ) {
# Video send
$hash->{sentMsgText} = "Image: ".TelegramBot_MsgForLog($msg,($isMedia<0)).((defined($addPar))?" - ".$addPar:"");
$hash->{HU_DO_PARAMS}->{url} = TelegramBot_getBaseURL($hash)."sendVideo";
# add caption
if (defined( $addPar) ) {
$addPar =~ s/(?<![\\])\\n/\x0A/g;
$addPar =~ s/(?<![\\])\\t/\x09/g;
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "caption", undef, $addPar, 0) if(!defined($ret));
$addPar = undef;
}
# add msg or file or stream
Log3($camname, 4, "$camname - SSCam_TBotSendIt: Filename for image file :".$fname.":");
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "video", undef, $msg, $isMedia) if(!defined($ret));
} else {
# nur Message senden
$msg = "No media File was created by SSCam. Can't send it.";
$hash->{HU_DO_PARAMS}->{url} = TelegramBot_getBaseURL($hash)."sendMessage";
my $parseMode = TelegramBot_AttrNum($name,"parseModeSend","0" );
if ($parseMode == 1) {
$parseMode = "Markdown";
} elsif ($parseMode == 2) {
$parseMode = "HTML";
} elsif ($parseMode == 3) {
$parseMode = 0;
if ($msg =~ /^markdown(.*)$/i) {
$msg = $1;
$parseMode = "Markdown";
} elsif ($msg =~ /^HTML(.*)$/i) {
$msg = $1;
$parseMode = "HTML";
}
} else {
$parseMode = 0;
}
Log3($camname, 4, "$camname - SSCam_TBotSendIt: parseMode $parseMode");
if (length($msg) > 1000) {
$hash->{sentMsgText} = substr($msg, 0, 1000)."...";
} else {
$hash->{sentMsgText} = $msg;
}
$msg =~ s/(?<![\\])\\n/\x0A/g;
$msg =~ s/(?<![\\])\\t/\x09/g;
# add msg (no file)
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "text", undef, $msg, 0) if(!defined($ret));
# add parseMode
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "parse_mode", undef, $parseMode, 0) if((!defined($ret)) && ($parseMode));
# add disable_web_page_preview
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "disable_web_page_preview", undef, JSON::true, 0)
if ((!defined($ret))&&(!AttrVal($name,'webPagePreview',1)));
}
if (defined($replyid)) {
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "reply_to_message_id", undef, $replyid, 0) if(!defined($ret));
}
if (defined($addPar)) {
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "reply_markup", undef, $addPar, 0) if(!defined($ret));
} elsif ($options =~ /-force_reply-/) {
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "reply_markup", undef, "{\"force_reply\":true}", 0 ) if(!defined($ret));
}
if ($options =~ /-silent-/) {
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, "disable_notification", undef, "true", 0) if(!defined($ret));
}
# finalize multipart
$ret = SSCam_TBotAddMultipart($hash, $fname, $hash->{HU_DO_PARAMS}, undef, undef, undef, 0) if(!defined($ret));
}
if (defined($ret)) {
Log3($camname, 3, "$camname - SSCam_TBotSendIt: Failed with :$ret:");
TelegramBot_Callback($hash->{HU_DO_PARAMS}, $ret, "");
} else {
$hash->{HU_DO_PARAMS}->{args} = \@args;
# if utf8 is set on string this will lead to length wrongly calculated in HTTPUtils (char instead of bytes) for some installations
if ((AttrVal($name,'utf8Special',0)) && (utf8::is_utf8($hash->{HU_DO_PARAMS}->{data}))) {
Log3 $camname, 4, "$camname - SSCam_TBotSendIt: utf8 encoding for data in message ";
utf8::downgrade($hash->{HU_DO_PARAMS}->{data});
}
Log3($camname, 4, "$camname - SSCam_TBotSendIt: timeout for sent :".$hash->{HU_DO_PARAMS}->{timeout}.": ");
HttpUtils_NonblockingGet($hash->{HU_DO_PARAMS});
}
return $ret;
}
####################################################################################################
# Telegram Media zusammenstellen
# Adaption der Sub "AddMultipart" aus TelegramBot
#
# Parameter:
# $hash = Hash des verwendeten TelegramBot-Devices !
# params = (hash for building up the data)
# paramname --> if not sepecifed / undef - multipart will be finished
# header for multipart
# content
# isFile to specify if content is providing a file to be read as content
#
# returns string in case of error or undef
####################################################################################################
sub SSCam_TBotAddMultipart($$$$$$$) {
my ($hash, $fname, $params, $parname, $parheader, $parcontent, $isMedia ) = @_;
my $name = $hash->{NAME};
my $ret;
# Check if boundary is defined
if ( ! defined( $params->{boundary} ) ) {
$params->{boundary} = "TelegramBot_boundary-x0123";
$params->{header} .= "\r\nContent-Type: multipart/form-data; boundary=".$params->{boundary};
$params->{method} = "POST";
$params->{data} = "";
}
# ensure parheader is defined and add final header new lines
$parheader = "" if (!defined($parheader));
$parheader .= "\r\n" if ((length($parheader) > 0) && ($parheader !~ /\r\n$/));
# add content
my $finalcontent;
if (defined($parname)) {
$params->{data} .= "--".$params->{boundary}."\r\n";
if ($isMedia > 0) {
# url decode filename
$parcontent = uri_unescape($parcontent) if(AttrVal($name,'filenameUrlEscape',0));
my $baseFilename = basename($parcontent);
$parheader = "Content-Disposition: form-data; name=\"".$parname."\"; filename=\"".$baseFilename."\"\r\n".$parheader."\r\n";
return("FAILED file :$parcontent: not found or empty" ) if(! -e $parcontent) ;
my $size = -s $parcontent;
my $limit = AttrVal($name,'maxFileSize',10485760);
return("FAILED file :$parcontent: is too large for transfer (current limit: ".$limit."B)") if($size > $limit) ;
$finalcontent = TelegramBot_BinaryFileRead($hash, $parcontent);
if ($finalcontent eq "") {
return("FAILED file :$parcontent: not found or empty");
}
} elsif ($isMedia < 0) {
my ($im, $ext) = SSCam_TBotIdentifyStream($hash, $parcontent);
$fname =~ s/.mp4$/.$ext/;
$parheader = "Content-Disposition: form-data; name=\"".$parname."\"; filename=\"".$fname."\"\r\n".$parheader."\r\n";
$finalcontent = $parcontent;
} else {
$parheader = "Content-Disposition: form-data; name=\"".$parname."\"\r\n".$parheader."\r\n";
$finalcontent = $parcontent;
}
$params->{data} .= $parheader.$finalcontent."\r\n";
} else {
return( "No content defined for multipart" ) if ( length( $params->{data} ) == 0 );
$params->{data} .= "--".$params->{boundary}."--";
}
return undef;
}
####################################################################################################
# Telegram Media Identifikation
# Adaption der Sub "IdentifyStream" aus TelegramBot
# $hash = Hash des verwendeten TelegramBot-Devices !
####################################################################################################
sub SSCam_TBotIdentifyStream($$) {
my ($hash, $msg) = @_;
# signatures for media files are documented here --> https://en.wikipedia.org/wiki/List_of_file_signatures
# seems sometimes more correct: https://wangrui.wordpress.com/2007/06/19/file-signatures-table/
# Video Signatur aus: https://www.garykessler.net/library/file_sigs.html
return (-1,"png") if ( $msg =~ /^\x89PNG\r\n\x1a\n/ ); # PNG
return (-1,"jpg") if ( $msg =~ /^\xFF\xD8\xFF/ ); # JPG not necessarily complete, but should be fine here
return (-30,"mpg") if ( $msg =~ /^....\x66\x74\x79\x70\x69\x73\x6f\x6d/ ); # mp4
return (0,undef);
} }
############################################################################################# #############################################################################################