48_BlinkCamera: Changed to new Oauth Authentication for Blink
git-svn-id: https://svn.fhem.de/fhem/trunk@30479 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it
|
# Do not insert empty lines here, update check depends on it
|
||||||
|
- change: 48_BlinkCamera: Changed to new Oauth Authentication for Blink
|
||||||
- bugfix: 98_vitoconnect: order of lists fixed
|
- bugfix: 98_vitoconnect: order of lists fixed
|
||||||
- feature: 76_SolarForecast: Version 1.60.0
|
- feature: 76_SolarForecast: Version 1.60.0
|
||||||
- feature: 98_vitoconnect: Message Übersetzung und Listen auch One Base
|
- feature: 98_vitoconnect: Message Übersetzung und Listen auch One Base
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ my $repositoryID = '$Id$';
|
|||||||
# Add alerts only for known cameras
|
# Add alerts only for known cameras
|
||||||
# video alert working for doorbells
|
# video alert working for doorbells
|
||||||
# camdisable/camenable not working for Lotus --> now with return message
|
# camdisable/camenable not working for Lotus --> now with return message
|
||||||
|
|
||||||
# 6.2.2023
|
# 6.2.2023
|
||||||
# added type for syncmodule
|
# added type for syncmodule
|
||||||
# added message for lveview being unsupported
|
# added message for lveview being unsupported
|
||||||
@@ -104,6 +103,18 @@ my $repositoryID = '$Id$';
|
|||||||
# liveview cmd will also set liveCam reading to identify stream
|
# liveview cmd will also set liveCam reading to identify stream
|
||||||
# getThumbnail for doorbells working
|
# getThumbnail for doorbells working
|
||||||
|
|
||||||
|
# 28.10.25 New oAuth protocol and 2fa
|
||||||
|
# replace verify pin with "authorize"
|
||||||
|
# add request2fa to get a new 2fa code for authorization
|
||||||
|
# "login" replaced with new "refresh" for refreshing authtoken
|
||||||
|
# add new tierinfo call after auth token received (done automatic. before homescreen)
|
||||||
|
# simplified header and agent generation
|
||||||
|
# store authtoken and refreshtoken in keyfile
|
||||||
|
# refresh (only once if atoken available but access denied) - to be checked
|
||||||
|
# 2.11.25 final oauth adaptations
|
||||||
|
# arm/disarm tested
|
||||||
|
# refresh for authtoken completed
|
||||||
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -113,20 +124,17 @@ my $repositoryID = '$Id$';
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# TASKS
|
# TASKS
|
||||||
#
|
#
|
||||||
|
# camenable/disable not working
|
||||||
|
# check if oauth expired triggers refresh correctly
|
||||||
|
# allow custom attribute for user-agent <major.minor>IOS_<build number>
|
||||||
#
|
#
|
||||||
#
|
# --- old ---
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# subtype for syncmodule needed?
|
# subtype for syncmodule needed?
|
||||||
# Button press?
|
# Button press?
|
||||||
# schlummermodus
|
# schlummermodus
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# Set thumbnail Req reading only after thumbnail stored (from internal)
|
# Set thumbnail Req reading only after thumbnail stored (from internal)
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# Analyze more information and settings
|
# Analyze more information and settings
|
||||||
#
|
#
|
||||||
# FIX: getThumbnail url failing sometimes
|
# FIX: getThumbnail url failing sometimes
|
||||||
@@ -136,16 +144,6 @@ my $repositoryID = '$Id$';
|
|||||||
# allow thumbnailreset
|
# allow thumbnailreset
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Ideas
|
|
||||||
#
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
#{"authtoken":{"authtoken":"sjkashajhdjkashd","message":"auth"},"networks":{"<n>":{"name":"<name>","onboarded":true}},"region":{"prde":"Europe"}}
|
|
||||||
#{"message":"Unauthorized Access"}
|
|
||||||
#
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
@@ -193,24 +191,20 @@ sub BlinkCamera_GetCamType( $$ );
|
|||||||
|
|
||||||
#########################
|
#########################
|
||||||
# Globals
|
# Globals
|
||||||
# OLD? my $BlinkCamera_host = "prod.immedia-semi.com";
|
|
||||||
#my $BlinkCamera_host = "rest.prir.immedia-semi.com";
|
|
||||||
#my $BlinkCamera_host = "rest.prde.immedia-semi.com";
|
|
||||||
|
|
||||||
my $BlinkCamera_hostpattern = "rest##sep####region##.immedia-semi.com";
|
my $BlinkCamera_hostpattern = "rest##sep####tier##.immedia-semi.com";
|
||||||
|
|
||||||
|
my $BlinkCamera_hostoauth = "api.oauth.blink.com";
|
||||||
|
|
||||||
|
my $BlinkCamera_useragent = "49.2IOS_2510241256";
|
||||||
|
|
||||||
|
|
||||||
my $BlinkCamera_header = "agent: TelegramBot/1.0\r\nUser-Agent: TelegramBot/1.0";
|
#my $BlinkCamera_header = "hardware_id: fhem test23";
|
||||||
# my $BlinkCamera_header = "agent: TelegramBot/1.0\r\nUser-Agent: TelegramBot/1.0\r\nAccept-Charset: utf-8";
|
my $BlinkCamera_header = "agent: TelegramBot/1.0";
|
||||||
|
|
||||||
my $BlinkCamera_loginjson = "{ \"password\" : \"q_password_q\", \"client_specifier\" : \"FHEM blinkCameraModule 1 - q_name_q\", \"email\" : \"q_email_q\" }";
|
my $BlinkCamera_oauthform = "username=q_email_q&password=q_password_q&grant_type=password&client_id=ios&scope=client";
|
||||||
#my $BlinkCamera_loginjsonV4 = "{ \"app_version\": \"6.0.10 (8280) #881c8812\", \"client_name\": \"fhem q_name_q\", \"client_type\": \"ios\", \"device_identifier\": \"fhem #q_fuuid_q\", \"email\": \"q_email_q\", \"os_version\": \"13\", \"password\": \"q_password_q\", \"reauth\": q_reauth_q, \"unique_id\": \"q_uniqueid_q\" }";
|
|
||||||
|
|
||||||
|
my $BlinkCamera_oauthformrefresh = "grant_type=refresh_token&refresh_token=q_token_q&client_id=ios&scope=client";
|
||||||
my $BlinkCamera_loginjsonV5 = "{ \"app_version\": \"6.2.7 (10212) \", \"client_name\": \"fhem q_name_q\", \"client_type\": \"ios\", \"device_identifier\": \"fhem q_fuuid_q\", \"email\": \"q_email_q\", \"os_version\": \"14.4\", \"password\": \"q_password_q\", \"reauth\": q_reauth_q, \"unique_id\": \"q_uniqueid_q\" }";
|
|
||||||
|
|
||||||
|
|
||||||
my $BlinkCamera_verifyPinjson = "{ \"pin\" : \"q_pin_q\" }";
|
|
||||||
|
|
||||||
my $BlinkCamera_configCamAlertjson = "{ \"camera\" : \"q_id_q\", \"id\" : \"q_id_q\", \"network\" : \"q_network_q\", \"motion_alert\" : \"q_alert_q\" }";
|
my $BlinkCamera_configCamAlertjson = "{ \"camera\" : \"q_id_q\", \"id\" : \"q_id_q\", \"network\" : \"q_network_q\", \"motion_alert\" : \"q_alert_q\" }";
|
||||||
|
|
||||||
@@ -238,10 +232,10 @@ my $BlinkCamera_videofile = "BlinkCamera/q_name_q/video/q_id_q.mp4";
|
|||||||
# special debug setting
|
# special debug setting
|
||||||
my $BlinkCamera_specialLog = 4;
|
my $BlinkCamera_specialLog = 4;
|
||||||
|
|
||||||
|
my $BlinkCamera_AuthorizationHeader = "Authorization: Bearer";
|
||||||
|
|
||||||
|
my $BlinkCamera_UserAgentHeader = "User-Agent:";
|
||||||
|
|
||||||
# NEw Header store for toekn auth
|
|
||||||
# my $BlinkCamera_TokenHeader = "TOKEN_AUTH";
|
|
||||||
my $BlinkCamera_TokenHeader = "token-auth";
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##############################################################################
|
##############################################################################
|
||||||
@@ -274,7 +268,7 @@ sub BlinkCamera_Initialize($) {
|
|||||||
"pollingTimeout ".
|
"pollingTimeout ".
|
||||||
"homeScreenV3:0,1 ".
|
"homeScreenV3:0,1 ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
@@ -370,6 +364,8 @@ sub BlinkCamera_Delete($$)
|
|||||||
|
|
||||||
setKeyValue( "BlinkCamera_".$hash->{Email}, undef );
|
setKeyValue( "BlinkCamera_".$hash->{Email}, undef );
|
||||||
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, undef );
|
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, undef );
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, undef );
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, undef );
|
||||||
|
|
||||||
Log3 $name, 4, "BlinkCamera_Delete $name: done ";
|
Log3 $name, 4, "BlinkCamera_Delete $name: done ";
|
||||||
return undef;
|
return undef;
|
||||||
@@ -406,11 +402,14 @@ sub BlinkCamera_Set($@)
|
|||||||
if ( $ret ) {
|
if ( $ret ) {
|
||||||
|
|
||||||
# do nothing if error/ret is defined
|
# do nothing if error/ret is defined
|
||||||
} elsif ($cmd eq 'login') {
|
} elsif ($cmd eq 'authorize') {
|
||||||
|
$ret = BlinkCamera_DoCmd( $hash, $cmd, $addArg );
|
||||||
|
|
||||||
|
} elsif ($cmd eq 'request2fa') {
|
||||||
$ret = BlinkCamera_DoCmd( $hash, $cmd );
|
$ret = BlinkCamera_DoCmd( $hash, $cmd );
|
||||||
|
|
||||||
} elsif ($cmd eq 'verifyPin') {
|
# } elsif ($cmd eq 'verifyPin') {
|
||||||
$ret = BlinkCamera_DoCmd( $hash, $cmd, $addArg );
|
# $ret = BlinkCamera_DoCmd( $hash, $cmd, $addArg );
|
||||||
|
|
||||||
} elsif( ($cmd eq 'camEnable') || ($cmd eq 'camDisable') ) {
|
} elsif( ($cmd eq 'camEnable') || ($cmd eq 'camDisable') ) {
|
||||||
$ret = BlinkCamera_CameraDoCmd( $hash, $cmd, $addArg )
|
$ret = BlinkCamera_CameraDoCmd( $hash, $cmd, $addArg )
|
||||||
@@ -426,6 +425,8 @@ sub BlinkCamera_Set($@)
|
|||||||
Log3 $name, 3, "BlinkCamera_Set $name: resetUniqueID requested ";
|
Log3 $name, 3, "BlinkCamera_Set $name: resetUniqueID requested ";
|
||||||
my $fuuid = $hash->{FUUID};
|
my $fuuid = $hash->{FUUID};
|
||||||
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, undef );
|
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, undef );
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, undef );
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, undef );
|
||||||
BlinkCamera_Setup( $hash );
|
BlinkCamera_Setup( $hash );
|
||||||
|
|
||||||
} elsif($cmd eq 'videoDelete') {
|
} elsif($cmd eq 'videoDelete') {
|
||||||
@@ -473,6 +474,9 @@ sub BlinkCamera_Get($@)
|
|||||||
} elsif($cmd eq 'getNetworks') {
|
} elsif($cmd eq 'getNetworks') {
|
||||||
$ret = BlinkCamera_DoCmd( $hash, "networks" );
|
$ret = BlinkCamera_DoCmd( $hash, "networks" );
|
||||||
|
|
||||||
|
} elsif($cmd eq 'getTierInfo') {
|
||||||
|
$ret = BlinkCamera_DoCmd( $hash, "tierinfo" );
|
||||||
|
|
||||||
} elsif ($cmd eq 'getInfoCamera') {
|
} elsif ($cmd eq 'getInfoCamera') {
|
||||||
return "BlinkCamera_Get: No value specified for get $cmd" if ( $numberOfArgs < 2 ) ;
|
return "BlinkCamera_Get: No value specified for get $cmd" if ( $numberOfArgs < 2 ) ;
|
||||||
$ret = BlinkCamera_CameraDoCmd( $hash, "cameraConfig", $arg );
|
$ret = BlinkCamera_CameraDoCmd( $hash, "cameraConfig", $arg );
|
||||||
@@ -565,7 +569,7 @@ sub BlinkCamera_Attr(@) {
|
|||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# INTERNAL: Function to send a command to the blink server
|
# INTERNAL: Function to send a command to the blink server
|
||||||
# cmd is login / arm / homescreen
|
# cmd is authorize / arm / homescreen /...
|
||||||
# par1/par2 are placeholder for addtl params
|
# par1/par2 are placeholder for addtl params
|
||||||
sub BlinkCamera_DoCmd($$;$$$)
|
sub BlinkCamera_DoCmd($$;$$$)
|
||||||
{
|
{
|
||||||
@@ -574,6 +578,13 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
my ( $cmd, $par1, $par2, $retryCount) = @args;
|
my ( $cmd, $par1, $par2, $retryCount) = @args;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $fuuid = $hash->{FUUID};
|
||||||
|
my ($terr, $authtoken) = getKeyValue("BlinkCamera_ATOKEN_".$fuuid);
|
||||||
|
if ( ( defined($terr) ) || ( ! defined($authtoken) ) ) {
|
||||||
|
# ignore error message here
|
||||||
|
$authtoken = undef;
|
||||||
|
}
|
||||||
|
|
||||||
$retryCount = 0 if ( ! defined( $retryCount ) );
|
$retryCount = 0 if ( ! defined( $retryCount ) );
|
||||||
|
|
||||||
# increase retrycount for next try
|
# increase retrycount for next try
|
||||||
@@ -599,13 +610,33 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# #######################
|
||||||
|
# # check for 2fa otherwise error
|
||||||
|
# if ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ( ! defined( $authtoken ) ) ) {
|
||||||
|
# Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to 2factor authorize not yet done ".$cmdString;
|
||||||
|
# return;
|
||||||
|
# }
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# check authentication otherwise queue the current cmd and do authenticate first
|
# check authentication otherwise queue the current cmd and do refresh (means 2fa refresh) first
|
||||||
if ( ($cmd ne "login") && ( ! defined( $hash->{AuthToken} ) ) ) {
|
if ( ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "tierinfo") && ($cmd ne "refresh") ) && ( ! defined( $authtoken ) ) ) {
|
||||||
# add to queue
|
# add to queue
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: add send to queue cmd ".$cmdString;
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: add send to queue cmd (do refresh first)".$cmdString;
|
||||||
push( @{ $hash->{cmdQueue} }, \@args );
|
push( @{ $hash->{cmdQueue} }, \@args );
|
||||||
$cmd = "login";
|
$cmd = "refresh";
|
||||||
|
$par1 = undef;
|
||||||
|
$par2 = undef;
|
||||||
|
# update cmdstring
|
||||||
|
$cmdString = "cmd :$cmd: ".(defined($par1)?" par1:".$par1.":":"").(defined($par2)?" par2:".$par2.":":"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# check tierinfo otherwise queue the current cmd and do tierinfo first
|
||||||
|
if ( ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "tierinfo") && ($cmd ne "refresh") ) && ( ! defined( $hash->{Tier} ) ) ) {
|
||||||
|
# add to queue
|
||||||
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: add send to queue cmd (do tierinfo first)".$cmdString;
|
||||||
|
push( @{ $hash->{cmdQueue} }, \@args );
|
||||||
|
$cmd = "tierinfo";
|
||||||
$par1 = undef;
|
$par1 = undef;
|
||||||
$par2 = undef;
|
$par2 = undef;
|
||||||
# update cmdstring
|
# update cmdstring
|
||||||
@@ -614,8 +645,7 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Check for invalid auth token and just remove cmds
|
# Check for invalid auth token and just remove cmds
|
||||||
if ( ($cmd ne "login") && ( $hash->{AuthToken} eq "INVALID" ) ) {
|
if ( ($cmd ne "refresh") && ( defined( $hash->{AuthToken} ) )&& ( $hash->{AuthToken} eq "INVALID" ) ) {
|
||||||
# add to queue
|
|
||||||
Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to invalid auth token ".$cmdString;
|
Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to invalid auth token ".$cmdString;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -627,9 +657,9 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
|
|
||||||
#######################
|
#######################
|
||||||
# check networks if not existing queue current cmd and get homescreen first
|
# check networks if not existing queue current cmd and get homescreen first
|
||||||
if ( ($cmd ne "login") && ($cmd ne "homescreen") && ($cmd ne "verifyPin") && ( ! defined( $net ) ) ) {
|
if ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "homescreen")&& ($cmd ne "tierinfo") && ($cmd ne "refresh") && ( ! defined( $net ) ) ) {
|
||||||
# add to queue
|
# add to queue
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: add send to queue cmd ".$cmdString;
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: add send to queue cmd (do homescreen first)".$cmdString;
|
||||||
push( @{ $hash->{cmdQueue} }, \@args );
|
push( @{ $hash->{cmdQueue} }, \@args );
|
||||||
$cmd = "homescreen";
|
$cmd = "homescreen";
|
||||||
$par1 = undef;
|
$par1 = undef;
|
||||||
@@ -640,19 +670,39 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Check for invalid auth token and just remove cmds
|
# Check for invalid auth token and just remove cmds
|
||||||
if ( ($cmd ne "login") && ($cmd ne "homescreen") && ($cmd ne "verifyPin") && ( $net eq "INVALID" ) ) {
|
if ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "homescreen")&& ($cmd ne "tierinfo") && ($cmd ne "refresh") && ( $net eq "INVALID" ) ) {
|
||||||
# add to queue
|
# add to queue
|
||||||
Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to invalid networks list (set attribute network) ".$cmdString;
|
Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to invalid networks list (set attribute network) ".$cmdString;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# Check for tier information
|
||||||
|
if ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "homescreen")&& ($cmd ne "tierinfo") && ($cmd ne "refresh") && ( ! defined( $hash->{Tier} ) ) ) {
|
||||||
|
# add to queue
|
||||||
|
Log3 $name, 2, "BlinkCamera_DoCmd $name: failed due to no tier information available ".$cmdString;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
my $ret;
|
my $ret;
|
||||||
|
|
||||||
$hash->{doStatus} = "WAITING";
|
$hash->{doStatus} = "WAITING";
|
||||||
$hash->{doStatus} .= " retry $retryCount" if ( $retryCount > 0 );
|
$hash->{doStatus} .= " retry $retryCount" if ( $retryCount > 0 );
|
||||||
|
|
||||||
$hash->{AuthToken} = "INVALID" if ($cmd eq "login");
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, "INVALID" ) if ($cmd eq "refresh");
|
||||||
|
|
||||||
|
if ( ($cmd eq "authorize") || ($cmd eq "request2fa") ) {
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, undef );
|
||||||
|
$authtoken = undef;
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, undef );
|
||||||
|
delete( $hash->{Tier} );
|
||||||
|
delete( $hash->{Account} );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ($cmd eq "tierinfo") ) {
|
||||||
|
delete( $hash->{Tier} );
|
||||||
|
delete( $hash->{Account} );
|
||||||
|
}
|
||||||
|
|
||||||
# reset networks reading for reading networks
|
# reset networks reading for reading networks
|
||||||
readingsSingleUpdate($hash, "networks", "INVALID", 0 ) if ( ($cmd eq "networks") );
|
readingsSingleUpdate($hash, "networks", "INVALID", 0 ) if ( ($cmd eq "networks") );
|
||||||
@@ -689,13 +739,16 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
$hash->{HU_DO_PARAMS}->{method} = "POST";
|
$hash->{HU_DO_PARAMS}->{method} = "POST";
|
||||||
|
|
||||||
my $dynhost = $BlinkCamera_hostpattern;
|
my $dynhost = $BlinkCamera_hostpattern;
|
||||||
my $region = ReadingsVal( $name, "region", "prde" );
|
my $tier = $hash->{Tier};
|
||||||
|
my $account = $hash->{Account};
|
||||||
|
|
||||||
if ($cmd eq "login") {
|
if ( ($cmd eq "authorize") || ($cmd eq "refresh") || ($cmd eq "request2fa") ) {
|
||||||
$dynhost =~ s/##region##/prod/;
|
$dynhost = $BlinkCamera_hostoauth;
|
||||||
# $dynhost =~ s/##sep##/-/;
|
|
||||||
|
} elsif ($cmd eq "tierinfo") {
|
||||||
|
$dynhost =~ s/##tier##/prod/;
|
||||||
} else {
|
} else {
|
||||||
$dynhost =~ s/##region##/$region/;
|
$dynhost =~ s/##tier##/$tier/;
|
||||||
# $dynhost =~ s/##sep##/./;
|
# $dynhost =~ s/##sep##/./;
|
||||||
}
|
}
|
||||||
$dynhost =~ s/##sep##/-/;
|
$dynhost =~ s/##sep##/-/;
|
||||||
@@ -704,66 +757,82 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
$hash->{HU_DO_PARAMS}->{header} = $BlinkCamera_header.
|
$hash->{HU_DO_PARAMS}->{header} = $BlinkCamera_header.
|
||||||
"\r\n"."Host: ".$dynhost;
|
"\r\n"."Host: ".$dynhost;
|
||||||
|
|
||||||
#######################
|
if ( ($cmd ne "authorize") && ($cmd ne "request2fa") && ($cmd ne "refresh") ) {
|
||||||
if ($cmd eq "login") {
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n"."Content-Type: application/json";
|
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_UserAgentHeader." ".$BlinkCamera_useragent;
|
||||||
|
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_AuthorizationHeader." ".$authtoken;
|
||||||
|
} else {
|
||||||
|
$hash->{HU_DO_PARAMS}->{header} .= "\r\n"."Content-Type: application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
my ($err, $uid_key) = getKeyValue("BlinkCamera_BLINKUID_".$fuuid);
|
||||||
|
if ( ( defined($err) ) || ( ! defined($uid_key) ) ) {
|
||||||
|
$uid_key = join "", map { unpack "H*", chr(rand(256)) } 1..16;
|
||||||
|
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, $uid_key );
|
||||||
|
}
|
||||||
|
$hash->{HU_DO_PARAMS}->{header} .= "\r\n"."hardware_id: fhem ".$uid_key;
|
||||||
|
|
||||||
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/oauth/token";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################
|
||||||
|
if (($cmd eq "authorize") || ($cmd eq "request2fa") ) {
|
||||||
|
|
||||||
|
if ($cmd eq "authorize") {
|
||||||
|
if ( defined( $par1 ) ) {
|
||||||
|
$hash->{HU_DO_PARAMS}->{header} .= "\r\n"."2fa-code: ".$par1;
|
||||||
|
} else {
|
||||||
|
$ret = "BlinkCamera_DoCmd $name: no 2fa code given for $cmd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $email = $hash->{Email};
|
my $email = $hash->{Email};
|
||||||
my ($err, $password) = getKeyValue("BlinkCamera_".$email);
|
my ($err, $password) = getKeyValue("BlinkCamera_".$email);
|
||||||
|
if ( ! $ret ) {
|
||||||
if(defined($err)) {
|
if(defined($err)) {
|
||||||
$ret = "BlinkCamera_DoCmd $name: password retrieval failed with :$err:";
|
$ret = "BlinkCamera_DoCmd $name: password retrieval failed with :$err:";
|
||||||
} elsif(! defined($password)) {
|
} elsif(! defined($password)) {
|
||||||
$ret = "BlinkCamera_DoCmd $name: password is empty";
|
$ret = "BlinkCamera_DoCmd $name: password is empty";
|
||||||
} else {
|
|
||||||
|
|
||||||
my $isReauth = "true";
|
|
||||||
my $fuuid = $hash->{FUUID};
|
|
||||||
my ($err, $uid_key) = getKeyValue("BlinkCamera_BLINKUID_".$fuuid);
|
|
||||||
if ( ( defined($err) ) || ( ! defined($uid_key) ) ) {
|
|
||||||
$uid_key = join "", map { unpack "H*", chr(rand(256)) } 1..16;
|
|
||||||
setKeyValue( "BlinkCamera_BLINKUID_".$fuuid, $uid_key );
|
|
||||||
$isReauth = "false";
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v5/account/login";
|
if ( ! $ret ) {
|
||||||
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_oauthform;
|
||||||
# $hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_loginjsonV4;
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_loginjsonV5;
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_password_q/$password/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_password_q/$password/g;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_email_q/$email/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_email_q/$email/g;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_name_q/$name/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_name_q/$name/g;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_uniqueid_q/$uid_key/g;
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_reauth_q/$isReauth/g;
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_fuuid_q/$fuuid/g;
|
|
||||||
|
|
||||||
|
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: loginV5 data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
|
||||||
|
|
||||||
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: oauthform data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
} elsif ( $cmd eq "verifyPin" ) {
|
} elsif ( $cmd eq "refresh" ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken}."\r\n"."Content-Type: application/json";
|
my ($trerr, $reftoken) = getKeyValue("BlinkCamera_RTOKEN_".$fuuid);
|
||||||
|
if ( ( defined($trerr) ) || ( ! defined($reftoken) ) ) {
|
||||||
|
# ignore error message here
|
||||||
|
$reftoken = undef;
|
||||||
|
}
|
||||||
|
$ret = "BlinkCamera_DoCmd $name: no refresh token found for $cmd" if ( !defined( $reftoken ) );
|
||||||
|
|
||||||
# /api/v4/account/<accountid>/client/<clientid>/pin/verify
|
if ( ! $ret ) {
|
||||||
#ORG $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v4/account/".$hash->{account}."/client/".$hash->{clientid}."/pin/verify";
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_oauthformrefresh;
|
||||||
$hash->{HU_DO_PARAMS}->{url} = "https://rest-e004.immedia-semi.com"."/api/v4/account/".$hash->{account}."/client/".$hash->{clientid}."/pin/verify";
|
|
||||||
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_token_q/$reftoken/g;
|
||||||
|
|
||||||
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: oauthformrefresh data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################
|
||||||
|
} elsif ( $cmd eq "tierinfo" ) {
|
||||||
|
|
||||||
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/users/tier_info";
|
||||||
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_verifyPinjson;
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_pin_q/$par1/g;
|
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: verify pin : ".$par1.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "camEnable") || ($cmd eq "camDisable" ) ) {
|
} elsif ( ($cmd eq "camEnable") || ($cmd eq "camDisable" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken}."\r\n"."Content-Type: application/json";
|
|
||||||
|
|
||||||
|
|
||||||
my $ctype = "invalid";
|
my $ctype = "invalid";
|
||||||
|
|
||||||
if ( ! defined( $net ) ) {
|
if ( ! defined( $net ) ) {
|
||||||
@@ -786,7 +855,7 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: cam type: ".$ctype.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: cam type: ".$ctype.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
} elsif ( $ctype eq "owl" ) {
|
} elsif ( $ctype eq "owl" ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/networks/".$net."/owls/".$par1."/config";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/owls/".$par1."/config";
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configOwljson;
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configOwljson;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
||||||
@@ -795,12 +864,12 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
# $ret = "BlinkCamera_DoCmd $name: camera type (".$ctype.") unsupported !!";
|
# $ret = "BlinkCamera_DoCmd $name: camera type (".$ctype.") unsupported !!";
|
||||||
|
|
||||||
if ($cmd eq "camEnable") {
|
if ($cmd eq "camEnable") {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}.
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account.
|
||||||
"/networks/".$net."/doorbells/".$par1."/config";
|
"/networks/".$net."/doorbells/".$par1."/config";
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configLotusjson;
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configLotusjson;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
||||||
} else {
|
} else {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}.
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account.
|
||||||
"/networks/".$net."/doorbells/".$par1."/disable";
|
"/networks/".$net."/doorbells/".$par1."/disable";
|
||||||
$hash->{HU_DO_PARAMS}->{data} = "";
|
$hash->{HU_DO_PARAMS}->{data} = "";
|
||||||
}
|
}
|
||||||
@@ -811,11 +880,59 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# #######################
|
||||||
|
# } elsif ( ($cmd eq "camEnable") || ($cmd eq "camDisable" ) ) {
|
||||||
|
|
||||||
|
# my $ctype = "invalid";
|
||||||
|
|
||||||
|
# if ( ! defined( $net ) ) {
|
||||||
|
# $ret = "BlinkCamera_DoCmd $name: no network identifier found for $cmd - set attribute";
|
||||||
|
# } else {
|
||||||
|
# $ctype = BlinkCamera_GetCamType( $hash, $par1 );
|
||||||
|
# }
|
||||||
|
|
||||||
|
# if ( ! $ret ) {
|
||||||
|
|
||||||
|
# my $alert = ($cmd eq "camEnable")?"true":"false";
|
||||||
|
|
||||||
|
# if ( $ctype eq "camera" ) {
|
||||||
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/network/".$net."/camera/".$par1."/update";
|
||||||
|
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configCamAlertjson;
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_id_q/$par1/g;
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_network_q/$net/g;
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_alert_q/$alert/g;
|
||||||
|
# Log3 $name, 4, "BlinkCamera_DoCmd $name: cam type: ".$ctype.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
|
# } elsif ( $ctype eq "owl" ) {
|
||||||
|
|
||||||
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/owls/".$par1."/config";
|
||||||
|
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configOwljson;
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
||||||
|
# Log3 $name, 4, "BlinkCamera_DoCmd $name: cam type: ".$ctype.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
|
# } elsif ( $ctype eq "lotus" ) {
|
||||||
|
# # $ret = "BlinkCamera_DoCmd $name: camera type (".$ctype.") unsupported !!";
|
||||||
|
|
||||||
|
# if ($cmd eq "camEnable") {
|
||||||
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account.
|
||||||
|
# "/networks/".$net."/doorbells/".$par1."/config";
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_configLotusjson;
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_value_q/$alert/g;
|
||||||
|
# } else {
|
||||||
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account.
|
||||||
|
# "/networks/".$net."/doorbells/".$par1."/disable";
|
||||||
|
# $hash->{HU_DO_PARAMS}->{data} = "";
|
||||||
|
# }
|
||||||
|
# Log3 $name, 4, "BlinkCamera_DoCmd $name: cam type: ".$ctype.": - data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
|
# } else {
|
||||||
|
# $ret = "BlinkCamera_DoCmd $name: camera type (".$ctype.") unknown !!";
|
||||||
|
# }
|
||||||
|
|
||||||
|
# }
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "arm") || ($cmd eq "disarm" ) ) {
|
} elsif ( ($cmd eq "arm") || ($cmd eq "disarm" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
if ( defined( $net ) ) {
|
if ( defined( $net ) ) {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/network/".$net."/".$cmd;
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/network/".$net."/".$cmd;
|
||||||
} else {
|
} else {
|
||||||
@@ -825,14 +942,10 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ($cmd eq "homescreen" ) {
|
} elsif ($cmd eq "homescreen" ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
my $acc = $hash->{account};
|
if ( defined( $account ) ) {
|
||||||
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v3/accounts/".$account."/".$cmd;
|
||||||
if ( defined( $acc ) ) {
|
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v3/accounts/".$acc."/".$cmd;
|
|
||||||
} else {
|
} else {
|
||||||
$ret = "BlinkCamera_DoCmd $name: no account id found for homescreen";
|
$ret = "BlinkCamera_DoCmd $name: no account id found for homescreen";
|
||||||
}
|
}
|
||||||
@@ -840,8 +953,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "networks" ) ) {
|
} elsif ( ($cmd eq "networks" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET" ;
|
$hash->{HU_DO_PARAMS}->{method} = "GET" ;
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/networks";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/networks";
|
||||||
@@ -850,8 +961,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "command" ) ) {
|
} elsif ( ($cmd eq "command" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
if ( defined( $net ) ) {
|
if ( defined( $net ) ) {
|
||||||
@@ -863,15 +972,13 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "alerts" ) ) {
|
} elsif ( ($cmd eq "alerts" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
# OLD V2 $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v2/videos/changed?page=".$par1."&since=".$hash->{alertUpdate};
|
# OLD V2 $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v2/videos/changed?page=".$par1."&since=".$hash->{alertUpdate};
|
||||||
|
|
||||||
# V1 seems still working here (v2 has been removed)
|
# V1 seems still working here (v2 has been removed)
|
||||||
# GET https://rest-prde.immedia-semi.com/api/v1/accounts/<id>/media/changed?since=2019-05-26T15%3A22%3A36Z&page=1
|
# GET https://rest-prde.immedia-semi.com/api/v1/accounts/<id>/media/changed?since=2019-05-26T15%3A22%3A36Z&page=1
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/media/changed?page=".$par1."&since=".$hash->{alertUpdate};
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/media/changed?page=".$par1."&since=".$hash->{alertUpdate};
|
||||||
# my $net = BlinkCamera_GetNetwork( $hash );
|
# my $net = BlinkCamera_GetNetwork( $hash );
|
||||||
# if ( defined( $net ) ) {
|
# if ( defined( $net ) ) {
|
||||||
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v2/videos?page=1";
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v2/videos?page=1";
|
||||||
@@ -883,8 +990,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "cameraConfig" ) ) {
|
} elsif ( ($cmd eq "cameraConfig" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
if ( defined( $net ) ) {
|
if ( defined( $net ) ) {
|
||||||
@@ -896,9 +1001,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "cameraThumbnail" ) ) {
|
} elsif ( ($cmd eq "cameraThumbnail" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "POST";
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = "";
|
$hash->{HU_DO_PARAMS}->{data} = "";
|
||||||
|
|
||||||
if ( defined( $net ) ) {
|
if ( defined( $net ) ) {
|
||||||
@@ -913,10 +1015,10 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
||||||
} elsif ( $ctype eq "owl" ) {
|
} elsif ( $ctype eq "owl" ) {
|
||||||
# https://rest-prde.immedia-semi.com/api/v1/accounts/<accid>/networks/<netid>/owls/<camid>/thumbnail
|
# https://rest-prde.immedia-semi.com/api/v1/accounts/<accid>/networks/<netid>/owls/<camid>/thumbnail
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/networks/".$net."/owls/".$par1."/thumbnail";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/owls/".$par1."/thumbnail";
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
||||||
} elsif ( $ctype eq "lotus" ) {
|
} elsif ( $ctype eq "lotus" ) {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/networks/".$net."/doorbells/".$par1."/thumbnail";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/doorbells/".$par1."/thumbnail";
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: $cmd cam type: ".$ctype.": ";
|
||||||
} else {
|
} else {
|
||||||
$ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unknown !!";
|
$ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unknown !!";
|
||||||
@@ -934,7 +1036,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
Log3 $name, 5, "BlinkCamera_DoCmd $name: par1 :".$par1.":";
|
Log3 $name, 5, "BlinkCamera_DoCmd $name: par1 :".$par1.":";
|
||||||
Log3 $name, 5, "BlinkCamera_DoCmd $name: curl :".(defined($curl)?$curl:"<undef>").":";
|
Log3 $name, 5, "BlinkCamera_DoCmd $name: curl :".(defined($curl)?$curl:"<undef>").":";
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
if ( defined( $curl ) ) {
|
if ( defined( $curl ) ) {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}.$curl.".jpg";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}.$curl.".jpg";
|
||||||
@@ -964,7 +1065,6 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
$par1 = $vid;
|
$par1 = $vid;
|
||||||
$hash->{HU_DO_PARAMS}->{par1} = $par1;
|
$hash->{HU_DO_PARAMS}->{par1} = $par1;
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
$hash->{HU_DO_PARAMS}->{method} = "GET";
|
||||||
|
|
||||||
if ( defined( $vidUrl ) ) {
|
if ( defined( $vidUrl ) ) {
|
||||||
@@ -1012,16 +1112,7 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
# "message": "Successfully deleted videos"
|
# "message": "Successfully deleted videos"
|
||||||
# }
|
# }
|
||||||
|
|
||||||
## OLD
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/media/delete";
|
||||||
# $hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken}."\r\n"."Content-Type: application/json";
|
|
||||||
|
|
||||||
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v3/videos/delete";
|
|
||||||
# $hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_deleteVideojson;
|
|
||||||
# $hash->{HU_DO_PARAMS}->{data} =~ s/q_id_q/$vid/g;
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken}."\r\n"."Content-Type: application/json";
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/media/delete";
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_deleteVideojson;
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_deleteVideojson;
|
||||||
$hash->{HU_DO_PARAMS}->{data} =~ s/q_id_q/$vid/g;
|
$hash->{HU_DO_PARAMS}->{data} =~ s/q_id_q/$vid/g;
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: data :".$hash->{HU_DO_PARAMS}->{data}.":";
|
||||||
@@ -1033,24 +1124,19 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
#######################
|
#######################
|
||||||
} elsif ( ($cmd eq "liveview" ) ) {
|
} elsif ( ($cmd eq "liveview" ) ) {
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{header} .= "\r\n".$BlinkCamera_TokenHeader.": ".$hash->{AuthToken};
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{method} = "POST";
|
|
||||||
|
|
||||||
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_liveviewjson;
|
$hash->{HU_DO_PARAMS}->{data} = $BlinkCamera_liveviewjson;
|
||||||
|
|
||||||
|
|
||||||
if ( defined( $net ) ) {
|
if ( defined( $net ) ) {
|
||||||
|
|
||||||
my $ctype = BlinkCamera_GetCamType( $hash, $par1 );
|
my $ctype = BlinkCamera_GetCamType( $hash, $par1 );
|
||||||
if ( $ctype eq "camera" ) {
|
if ( $ctype eq "camera" ) {
|
||||||
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/network/".$net."/camera/".$par1."/liveview";
|
# $hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/network/".$net."/camera/".$par1."/liveview";
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v5/accounts/".$hash->{account}."/networks/".$net."/cameras/".$par1."/liveview";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v5/accounts/".$account."/networks/".$net."/cameras/".$par1."/liveview";
|
||||||
} elsif ( $ctype eq "owl" ) {
|
} elsif ( $ctype eq "owl" ) {
|
||||||
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$hash->{account}."/networks/".$net."/owls/".$par1."/liveview";
|
$hash->{HU_DO_PARAMS}->{url} = $hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/owls/".$par1."/liveview";
|
||||||
} elsif ( $ctype eq "lotus" ) {
|
} elsif ( $ctype eq "lotus" ) {
|
||||||
$hash->{HU_DO_PARAMS}->{url} =
|
$hash->{HU_DO_PARAMS}->{url} =
|
||||||
$hash->{URL}."/api/v1/accounts/".$hash->{account}."/networks/".$net."/doorbells/".$par1."/liveview";
|
$hash->{URL}."/api/v1/accounts/".$account."/networks/".$net."/doorbells/".$par1."/liveview";
|
||||||
# $ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unsupported !!";
|
# $ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unsupported !!";
|
||||||
} else {
|
} else {
|
||||||
$ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unknown !!";
|
$ret = "BlinkCamera_DoCmd $name: $cmd camera type (".$ctype.") unknown !!";
|
||||||
@@ -1075,6 +1161,9 @@ sub BlinkCamera_DoCmd($$;$$$)
|
|||||||
$hash->{HU_DO_PARAMS}->{args} = \@args;
|
$hash->{HU_DO_PARAMS}->{args} = \@args;
|
||||||
|
|
||||||
Log3 $name, 4, "BlinkCamera_DoCmd $name: call url :".$hash->{HU_DO_PARAMS}->{url}.": ";
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: call url :".$hash->{HU_DO_PARAMS}->{url}.": ";
|
||||||
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: header :".$hash->{HU_DO_PARAMS}->{header}.": ";
|
||||||
|
Log3 $name, 4, "BlinkCamera_DoCmd $name: data : ".$hash->{HU_DO_PARAMS}->{data}.": ";
|
||||||
|
|
||||||
HttpUtils_NonblockingGet( $hash->{HU_DO_PARAMS} );
|
HttpUtils_NonblockingGet( $hash->{HU_DO_PARAMS} );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1145,80 +1234,97 @@ sub BlinkCamera_Deepencode
|
|||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# INTERNAL: Parse the login results
|
# INTERNAL: Parse the oauth results
|
||||||
sub BlinkCamera_ParseLogin($$$)
|
sub BlinkCamera_ParseOAuthToken($$$$)
|
||||||
|
{
|
||||||
|
my ( $hash, $result, $readUpdates, $cmd ) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
#
|
||||||
|
# {"access_token":".....","expires_in":14400,
|
||||||
|
# "refresh_token":"...","scope":"client","token_type":"Bearer"}
|
||||||
|
#
|
||||||
|
|
||||||
|
my $fuuid = $hash->{FUUID};
|
||||||
|
if ( defined( $result->{access_token} ) ) {
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, $result->{access_token} );
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, $result->{refresh_token} );
|
||||||
|
|
||||||
|
Log3 $name, 4, "BlinkCamera_Callback $name: OAuth expires :".$result->{expires_in}.":" ;
|
||||||
|
Log3 $name, 4, "BlinkCamera_Callback $name: OAuth scope :".$result->{scope}.":" ;
|
||||||
|
Log3 $name, 4, "BlinkCamera_Callback $name: OAuth token_type :".$result->{token_type}.":" ;
|
||||||
|
} else {
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, undef );
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, undef );
|
||||||
|
$ret = "Auth failed: no access token received in result!";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# INTERNAL: Parse the response on 2fa request (content not relevant)
|
||||||
|
sub BlinkCamera_Parse2faResponse($$$)
|
||||||
{
|
{
|
||||||
my ( $hash, $result, $readUpdates ) = @_;
|
my ( $hash, $result, $readUpdates ) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
# !! removed old homescreen - 2020-10-12
|
|
||||||
my $ret;
|
my $ret;
|
||||||
|
|
||||||
if ( defined( $result->{account} ) ) {
|
#
|
||||||
my $acc = $result->{account};
|
# {"next_time_in_secs":60,"phone":"+49xxxx....","tsv_state":"sms"}
|
||||||
if ( defined( $acc->{account_id} ) ) {
|
#
|
||||||
$hash->{account} = $acc->{account_id};
|
|
||||||
}
|
if ( defined( $result->{next_time_in_secs} ) ) {
|
||||||
# V5
|
$hash->{tfaResponse} = $result;
|
||||||
if ( defined( $acc->{client_id} ) ) {
|
|
||||||
$hash->{clientid} = $acc->{client_id};
|
Log3 $name, 4, "BlinkCamera_Callback $name: 2faResponse phone :".$result->{phone}.":" ;
|
||||||
}
|
Log3 $name, 4, "BlinkCamera_Callback $name: 2faResponse tsv_state :".$result->{tsv_state}.":" ;
|
||||||
if ( defined( $acc->{client_verification_required} ) ) {
|
|
||||||
$hash->{clientverreq} = $acc->{client_verification_required};
|
|
||||||
}
|
|
||||||
if ( defined( $acc->{phone_verification_required} ) ) {
|
|
||||||
$hash->{phoneverreq} = $acc->{phone_verification_required};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# V4
|
|
||||||
# if ( defined( $result->{authtoken} ) ) {
|
|
||||||
# my $at = $result->{authtoken};
|
|
||||||
# if ( defined( $at->{authtoken} ) ) {
|
|
||||||
# $hash->{AuthToken} = $at->{authtoken};
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# V5
|
|
||||||
if ( defined( $result->{auth} ) ) {
|
|
||||||
my $au = $result->{auth};
|
|
||||||
if ( defined( $au->{token} ) ) {
|
|
||||||
$hash->{AuthToken} = $au->{token};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# V4
|
|
||||||
# if ( defined( $result->{client} ) ) {
|
|
||||||
# my $clt = $result->{client};
|
|
||||||
# if ( defined( $clt->{id} ) ) {
|
|
||||||
# $hash->{clientid} = $clt->{id};
|
|
||||||
# $hash->{clientverreq} = $clt->{verification_required};
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# V4
|
|
||||||
# my $resreg = $result->{region};
|
|
||||||
# if ( defined( $resreg ) ) {
|
|
||||||
# $readUpdates->{region} = $resreg->{tier};
|
|
||||||
# $readUpdates->{regionName} = $resreg->{description};
|
|
||||||
# } else {
|
|
||||||
# $readUpdates->{region} = undef;
|
|
||||||
# $readUpdates->{regionName} = undef;
|
|
||||||
# }
|
|
||||||
|
|
||||||
# V5
|
|
||||||
my $resreg = $result->{account};
|
|
||||||
if ( defined( $resreg ) ) {
|
|
||||||
$readUpdates->{region} = $resreg->{tier};
|
|
||||||
$readUpdates->{regionName} = $resreg->{region};
|
|
||||||
} else {
|
|
||||||
$readUpdates->{region} = undef;
|
|
||||||
$readUpdates->{regionName} = undef;
|
|
||||||
}
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# INTERNAL: Parse the tier info --> requiested ties for host and account for urls
|
||||||
|
sub BlinkCamera_ParseTierinfo($$$)
|
||||||
|
{
|
||||||
|
my ( $hash, $result, $readUpdates ) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
#
|
||||||
|
# {"tier":"e004","account_id":zzz,"tulsa_id":zzz}
|
||||||
|
#
|
||||||
|
|
||||||
|
if ( defined( $result->{tier} ) ) {
|
||||||
|
$hash->{Tier} = $result->{tier};
|
||||||
|
$readUpdates->{region} = $result->{tier};
|
||||||
|
|
||||||
|
if ( defined( $result->{account_id} ) ) {
|
||||||
|
$hash->{Account} = $result->{account_id};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$readUpdates->{region} = undef;
|
||||||
|
delete( $hash->{Tier} );
|
||||||
|
delete( $hash->{Account} );
|
||||||
|
|
||||||
|
$ret = "Tierinfo failed: no tier info found in result!";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# INTERNAL: Parse the networks results
|
# INTERNAL: Parse the networks results
|
||||||
sub BlinkCamera_ParseNetworks($$$)
|
sub BlinkCamera_ParseNetworks($$$)
|
||||||
@@ -1232,7 +1338,7 @@ sub BlinkCamera_ParseNetworks($$$)
|
|||||||
my $resnet = $result->{summary};
|
my $resnet = $result->{summary};
|
||||||
my $netlist = "";
|
my $netlist = "";
|
||||||
if ( defined( $resnet ) ) {
|
if ( defined( $resnet ) ) {
|
||||||
Log3 $name, 4, "BlinkCamera_Callback $name: login number of networks ".scalar(keys %$resnet) ;
|
Log3 $name, 4, "BlinkCamera_Callback $name: networks number of networks ".scalar(keys %$resnet) ;
|
||||||
foreach my $netkey ( keys %$resnet ) {
|
foreach my $netkey ( keys %$resnet ) {
|
||||||
Log3 $name, 4, "BlinkCamera_Callback $name: network ".$netkey ;
|
Log3 $name, 4, "BlinkCamera_Callback $name: network ".$netkey ;
|
||||||
my $net = $resnet->{$netkey};
|
my $net = $resnet->{$netkey};
|
||||||
@@ -1338,10 +1444,6 @@ sub BlinkCamera_ParseHomescreen($$$)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# sync module information
|
# sync module information
|
||||||
my $syncList = $result->{sync_modules};
|
my $syncList = $result->{sync_modules};
|
||||||
|
|
||||||
@@ -1655,17 +1757,28 @@ sub BlinkCamera_Callback($$$)
|
|||||||
my $polling = ( defined($par2) ) && ($par2 eq "POLLING" );
|
my $polling = ( defined($par2) ) && ($par2 eq "POLLING" );
|
||||||
my $hidden = ( ( defined($par2) ) && ($par2 eq "HIDDEN" ) ) || $polling;
|
my $hidden = ( ( defined($par2) ) && ($par2 eq "HIDDEN" ) ) || $polling;
|
||||||
|
|
||||||
|
# my $specialcase = 1;
|
||||||
|
|
||||||
my $fullurl;
|
my $fullurl;
|
||||||
my $repfilename;
|
my $repfilename;
|
||||||
|
|
||||||
|
my $httpcode = ( defined($param->{code}) )?$param->{code}:0;
|
||||||
|
|
||||||
Log3 $name, 4, "BlinkCamera_Callback $name: called from ".($polling?"Polling":($hidden?"Hidden":"DoCmd"));
|
Log3 $name, 4, "BlinkCamera_Callback $name: called from ".($polling?"Polling":($hidden?"Hidden":"DoCmd"));
|
||||||
|
|
||||||
Log3 $name, 4, "BlinkCamera_Callback $name: ".
|
Log3 $name, 4, "BlinkCamera_Callback $name: ".
|
||||||
(defined( $err )?"status err :".$err:"").
|
(defined( $err )?"status err :".$err:"").
|
||||||
|
(defined( $httpcode )?"status code :".$httpcode:"undef").
|
||||||
(defined( $filename )?
|
(defined( $filename )?
|
||||||
": data length ".(( defined( $data ) )?length($data):"<undefined>")." filename :".$filename.":" :
|
": data length ".(( defined( $data ) )?length($data):"<undefined>")." filename :".$filename.":" :
|
||||||
": data ".(( defined( $data ) )?$data:"<undefined>"));
|
": data ".(( defined( $data ) )?$data:"<undefined>"));
|
||||||
|
|
||||||
|
$hash->{cmdCode} = $httpcode;
|
||||||
|
|
||||||
|
if ( ( defined($httpcode) ) && ( $httpcode != 200 ) ) {
|
||||||
|
Log3 $name, 3, "BlinkCamera_Callback $name: request returned http status: ".$httpcode;
|
||||||
|
}
|
||||||
|
|
||||||
# Check for timeout "read from $hash->{addr} timed out"
|
# Check for timeout "read from $hash->{addr} timed out"
|
||||||
if ( $err =~ /^read from.*timed out$/ ) {
|
if ( $err =~ /^read from.*timed out$/ ) {
|
||||||
$ret = "NonBlockingGet timed out on read from ".($param->{hideurl}?"<hidden>":$param->{url})." after ".$param->{timeout}."s";
|
$ret = "NonBlockingGet timed out on read from ".($param->{hideurl}?"<hidden>":$param->{url})." after ".$param->{timeout}."s";
|
||||||
@@ -1713,7 +1826,7 @@ sub BlinkCamera_Callback($$$)
|
|||||||
$ret = "Callback returned no valid JSON !";
|
$ret = "Callback returned no valid JSON !";
|
||||||
} elsif ( ref( $jo ) ne "HASH" ) {
|
} elsif ( ref( $jo ) ne "HASH" ) {
|
||||||
$ret = "Callback returned no valid JSON (no hash: ".ref( $jo ).")!";
|
$ret = "Callback returned no valid JSON (no hash: ".ref( $jo ).")!";
|
||||||
} elsif ( $jo->{message} ) {
|
} elsif ( ( $jo->{message} ) ) {
|
||||||
$ret = "Callback returned error:".$jo->{message}.":";
|
$ret = "Callback returned error:".$jo->{message}.":";
|
||||||
|
|
||||||
$ret = "SUCCESS" if ( $jo->{message} =~ /^Successfully / );
|
$ret = "SUCCESS" if ( $jo->{message} =~ /^Successfully / );
|
||||||
@@ -1721,9 +1834,13 @@ sub BlinkCamera_Callback($$$)
|
|||||||
# special case for pin verification: Client has been successfully verified
|
# special case for pin verification: Client has been successfully verified
|
||||||
$ret = "SUCCESS" if ( $jo->{message} =~ /^Client has been successfully / );
|
$ret = "SUCCESS" if ( $jo->{message} =~ /^Client has been successfully / );
|
||||||
|
|
||||||
# reset authtoken if {"message":"Unauthorized Access"} --> will be re checked on next call
|
my $fuuid = $hash->{FUUID};
|
||||||
delete( $hash->{AuthToken} ) if ( $jo->{message} eq "Unauthorized Access" );
|
if ( ( $jo->{message} eq "Unauthorized Access" ) ) {
|
||||||
|
# reset authtoken if {"message":"Unauthorized Access"} --> will be re checked on next call
|
||||||
|
setKeyValue( "BlinkCamera_ATOKEN_".$fuuid, undef );
|
||||||
|
# also clean refreshtoken if refresh did fail
|
||||||
|
setKeyValue( "BlinkCamera_RTOKEN_".$fuuid, undef ) if ( $cmd eq "refresh" );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$result = $jo;
|
$result = $jo;
|
||||||
}
|
}
|
||||||
@@ -1749,8 +1866,14 @@ sub BlinkCamera_Callback($$$)
|
|||||||
Log3 $name, 4, "BlinkCamera_Callback $name: analyze result for cmd:$cmd:";
|
Log3 $name, 4, "BlinkCamera_Callback $name: analyze result for cmd:$cmd:";
|
||||||
|
|
||||||
# handle different commands
|
# handle different commands
|
||||||
if ( $cmd eq "login" ) {
|
if ( ( $cmd eq "authorize" ) || ( $cmd eq "refresh" ) ) {
|
||||||
$ret = BlinkCamera_ParseLogin( $hash, $result, \%readUpdates );
|
$ret = BlinkCamera_ParseOAuthToken( $hash, $result, \%readUpdates, $cmd );
|
||||||
|
|
||||||
|
} elsif ( ($cmd eq "request2fa") ) {
|
||||||
|
$ret = BlinkCamera_Parse2faResponse( $hash, $result, \%readUpdates );
|
||||||
|
|
||||||
|
} elsif ( ($cmd eq "tierinfo") ) {
|
||||||
|
$ret = BlinkCamera_ParseTierinfo( $hash, $result, \%readUpdates );
|
||||||
|
|
||||||
} elsif ( ($cmd eq "networks") ) {
|
} elsif ( ($cmd eq "networks") ) {
|
||||||
$ret = BlinkCamera_ParseNetworks( $hash, $result, \%readUpdates );
|
$ret = BlinkCamera_ParseNetworks( $hash, $result, \%readUpdates );
|
||||||
@@ -2090,8 +2213,8 @@ sub BlinkCamera_Setup($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my %sets = (
|
my %sets = (
|
||||||
"login" => undef,
|
"request2fa" => undef,
|
||||||
"verifyPin" => undef,
|
"authorize" => undef,
|
||||||
|
|
||||||
"arm" => undef,
|
"arm" => undef,
|
||||||
"disarm" => undef,
|
"disarm" => undef,
|
||||||
@@ -2115,6 +2238,8 @@ sub BlinkCamera_Setup($) {
|
|||||||
"getInfo" => undef,
|
"getInfo" => undef,
|
||||||
"getInfoCamera" => undef,
|
"getInfoCamera" => undef,
|
||||||
|
|
||||||
|
"getTierInfo" => undef,
|
||||||
|
|
||||||
"getThumbnail" => undef,
|
"getThumbnail" => undef,
|
||||||
|
|
||||||
"getVideoAlert" => undef,
|
"getVideoAlert" => undef,
|
||||||
@@ -2154,10 +2279,14 @@ sub BlinkCamera_Setup($) {
|
|||||||
delete( $hash->{cmd} );
|
delete( $hash->{cmd} );
|
||||||
delete( $hash->{cmdResult} );
|
delete( $hash->{cmdResult} );
|
||||||
delete( $hash->{cmdJson} );
|
delete( $hash->{cmdJson} );
|
||||||
|
delete( $hash->{cmdCode} );
|
||||||
|
|
||||||
delete( $hash->{pollResult} );
|
delete( $hash->{pollResult} );
|
||||||
|
|
||||||
delete( $hash->{AuthToken} );
|
delete( $hash->{AuthToken} );
|
||||||
|
delete( $hash->{RefreshToken} );
|
||||||
|
delete( $hash->{Tier} );
|
||||||
|
delete( $hash->{Account} );
|
||||||
|
|
||||||
delete( $hash->{videos} );
|
delete( $hash->{videos} );
|
||||||
delete( $hash->{updateTimestamp} );
|
delete( $hash->{updateTimestamp} );
|
||||||
@@ -2416,7 +2545,6 @@ sub BlinkCamera_GetAlertEntry( $$ ) {
|
|||||||
$entrystring .= $jentry->{created_at} if ( defined( $jentry->{created_at} ) );
|
$entrystring .= $jentry->{created_at} if ( defined( $jentry->{created_at} ) );
|
||||||
$entrystring .= "|";
|
$entrystring .= "|";
|
||||||
|
|
||||||
|
|
||||||
$updated = $jentry->{updated_at} if ( defined( $jentry->{updated_at} ) );
|
$updated = $jentry->{updated_at} if ( defined( $jentry->{updated_at} ) );
|
||||||
$entrystring .= $updated;
|
$entrystring .= $updated;
|
||||||
$entrystring .= "|";
|
$entrystring .= "|";
|
||||||
@@ -2631,6 +2759,10 @@ sub BlinkCamera_AnalyzeAlertResults( $$$ ) {
|
|||||||
<br>
|
<br>
|
||||||
The blink device also contains a proxy for retrieving videos and thumbnails throug an FHEMweb extension in the form of http://<fhem>:<fhemwebport>/fhem/BlinkCamera/<name of the blink device>/...
|
The blink device also contains a proxy for retrieving videos and thumbnails throug an FHEMweb extension in the form of http://<fhem>:<fhemwebport>/fhem/BlinkCamera/<name of the blink device>/...
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<br>
|
||||||
|
Note (2025-11): New OAuth login method is now mandatory for blink. The new process after defining the device in fhem is to manually call <code>set <blink device> request2fa</code>. The code received on your mobile can then be used to start the authorization process with <code>set <blink device> authorize <2fa code></code>. With this call authorization should be able to get an authorization code and also a token to refresh the code after some time. In other words after succesfull authorization regular polling is supposed to work.
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
<a name="BlinkCameradefine"></a>
|
<a name="BlinkCameradefine"></a>
|
||||||
<b>Define</b>
|
<b>Define</b>
|
||||||
@@ -2654,9 +2786,9 @@ sub BlinkCamera_AnalyzeAlertResults( $$$ ) {
|
|||||||
where <what> / <value> is one of
|
where <what> / <value> is one of
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
<li><code>login</code><br>Initiate a login to the blink servers. This is usually done automatically when needed or when the login is expired
|
<li><code>request2fa</code><br>Initiate a request for a 2fa code send normally as sms to your mobile (this code is neededed for successfully authorizing fhem - see authorize
|
||||||
</li>
|
</li>
|
||||||
<li><code>verifyPin</code><br>can be used to verify the pin send from blink via email/sms
|
<li><code>authorize <2fa code></code><br>needed to login and authorize fhem to access the blink APIs. providing the 2fa code received from blink is needed to use the authorize command
|
||||||
</li>
|
</li>
|
||||||
<li><code>arm</code> or <code>disarm</code><br>All enabled cameras in the system will be armed (i.e. they will be set to a mode where alarms/videos are automatically created based on the current settings) / disarmed (set to inactive mode where no video is recorded.
|
<li><code>arm</code> or <code>disarm</code><br>All enabled cameras in the system will be armed (i.e. they will be set to a mode where alarms/videos are automatically created based on the current settings) / disarmed (set to inactive mode where no video is recorded.
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user