I am forcing a bunch of Blink cams to take snapshots every 10 minutes.
That part has been working a-ok 98% of the time.
98% because, with Blink, the snapshot requests cannot be made back-to-back.
Instead they need to be spaced about 30 seconds apart or Blink will throw a "System Busy… " error.
Mostly 30 seconds works, but every so often it bites The Big One.
So I tried to add error trapping to the script - hoping to trap the error (which the trap sees as a 409) and then wait 30 seconds and re-issue the request for the same cam.
It actually seems like it might be working, but I do not know enough about the PS environment or Blink to be 100% sure.
What I am hoping for is Somebody Who Knows to take a look at the code and tell me if it, at least, looks like it should wait N seconds and then re-try the same cam
Here’s the code; scroll down to function TakeSnapshotFromOneCamera to see the attempted error trapping.
# PURPOSE: To force a snapshot from each camera in the system every 10 minutes
#
# NOTES: Code copied from Ryan's(@naryk) much larger, much more comprehensive script.
#
# CHANGES: 2019 04-09: - Modified the Win 7 box thusly:
# * Downloaded/installed Windows Management Framework 5.1
# * Downloaded/installed .NET Framework 4.7.2 DevPack FROM https://dotnet.microsoft.com/download
# - Carved away almost all of Andrew's code leaving just snapshots
# 2019 04-12: - Fixed incorrect references to email and password
# 2019 04-12 - Added error trapping to TakeSnapshotFromOneCamera for "System is busy... code :307", although
# the trapping seems to see "409) Conflict" instead.
# 2019 04-14 - Modified error trapping
# ----------------------------------
# Blink Credentials for your system:
$blinkAccountEmail = "x@y.com"
$blinkAccountPassword = "xxx"
# ----------------------------------
# Determine how many seconds we want to
# wait between individual snapshots.
# If we try too soon, we get a "System Busy"
# error - which comes back to error trapping
# as a 409 error.
$secondsBetweenSnapshots = 30
# ----------------------------------
# Determine how many times we want to re-try
# telling a given cam to take a snspshot in
# event of above-mentioned 409 error.
$numberOfSnapshotRetries = 3
# ----------------------------------
# Specify Blink's API Server, this is the URL you are
# directed to when you are prompted for IFTTT Integration
# to "Grant Access".
# You can verify this yourself to make sure you are sending
# the data where you expect it to be
$blinkAPIServer = 'prod.immedia-semi.com'
# Use the server below if you are in Germany
#$blinkAPIServer = 'prde.immedia-semi.com'
# ----------------------------------
# Concoct headers to send to Blink's
# server for authentication
$authenticationHeaders =
@{
"Host" = "$blinkAPIServer"
"Content-Type" = "application/json"
}
# ----------------------------------
# Concoct credential data
$credentials =
@{
"email" = $blinkAccountEmail
"password" = $blinkAccountPassword
} | ConvertTo-Json
# ----------------------------------
# Specify login URL of Blink API
$BlinkLoginURL = "https://$blinkAPIServer/login"
# ----------------------------------
# Authenticate credentials with Blink
# Server and get our token for future requests
$response = Invoke-RestMethod -UseBasicParsing $BlinkLoginURL -Method Post -Headers $authenticationHeaders -Body $credentials
if(-not $response)
{
echo "Invalid Blink credentials provided. Please verify email and password in this script's code."
exit
}
# ----------------------------------
# Get the object data
$region = $response.region.psobject.properties.name
$authToken = $response.authtoken.authtoken
# ----------------------------------
# Concoct headers to send to Blink's
# server after authentication with our token
$workingHeaders =
@{
"Host" = "$blinkAPIServer"
"TOKEN_AUTH" = "$authToken"
}
# ----------------------------------------------------------------------------------------------------
function TakeSnapshotFromOneCamera
{
# PURPOSE: To force one camera to take one snapshot
# NOTES: 1) Sometimes we do not allow enough time between snapshots
# and the system is busy. To deal with that, we allow
# up to N attempts to take the snapshot before reporting an error.
param (
[Parameter(Mandatory=$true)]
[string]$NetworkId,
[string]$CameraId,
[string]$CameraName
)
$finished = $false
$retryCount = 0
While (-not $finished)
{
Try
{
$curURL = 'https://rest-'+ $region +".immedia-semi.com/network/$NetworkId/camera/$CameraId/thumbnail"
$response = Invoke-RestMethod -UseBasicParsing $curURL -Method Post -Headers $workingHeaders -ErrorAction Stop
# Get list of cameras
$curURL = 'https://rest-'+ $region +".immedia-semi.com/network/$NetworkId/camera/$cameraId"
$response = Invoke-RestMethod -UseBasicParsing $curURL -Method Get -Headers $workingHeaders -ErrorAction Stop
#$cameraThumbnail = $response.camera_status.thumbnail
$finished = $true
}
Catch
{
if ($retryCount -ge $numberOfSnapshotRetries)
{
$curTimeStamp = Get-Date -DisplayHint DateTime
$curLineNumber = $_.InvocationInfo.ScriptLineNumber
$curFailedItem = $_.Exception.ItemName
$curExceptionMessage = $_.Exception.Message
$curInnerExceptionMessage = $_.Exception.InnerException
Write-Host $curTimeStamp "Line" $curLineNumber $cameraName
Write-Host " " $curFailedItem $curExceptionMessage
#Write-Host " " $curInnerExceptionMessage
throw
}
else
{
if ($retryCount -gt 0)
{
write-Host "$CameraName Retries=$retryCount"
}
Start-Sleep -s $secondsBetweenSnapshots
$retryCount++
}
}
}
}
# ----------------------------------------------------------------------------------------------------
function TakeSnapshotFromEachCamera
{
$curURL = 'https://rest-'+ $region +".immedia-semi.com/api/v1/camera/usage"
$sync_units = Invoke-RestMethod -UseBasicParsing $curURL -Method Get -Headers $workingHeaders
foreach($network in $sync_units.networks)
{
$cameras = $network.cameras
$curNetwork_id = $network.network_id
$count = 1
foreach($camera in $cameras)
{
$curCamera_id = $camera.id
$curCameraName = $camera.name
#echo "$curCameraName"
$count += 1
TakeSnapshotFromOneCamera -NetworkId $curNetwork_id -CameraId $curCamera_id -CameraName $curCameraName
# ------------------------------------------------------------
# We need to wait at least a certain number of seconds between
# snapshots to avoid "System is busy, please wait","code":307}
Start-Sleep -s $secondsBetweenSnapshots
}
}
}
# ======================================================================
# MAIN PROCEDURE: Force a snapshot from each camera every 10 minutes
#
# Sleep seconds were strictly trial-and-error to get to a 10 min
# interval between snapshots for the cams - including the seconds
# between snaps to avoid "System is Busy..." errors.
do{
$totalCount +=1
$curTimeStamp = Get-Date -DisplayHint DateTime
#Write-Host " "
Write-Host "Count=$totalCount $curTimeStamp"
#Write-Host "-----------------------------"
TakeSnapshotFromEachCamera
Start-Sleep -s 138
} while (1)
# ========================= End of Code =================================