Reputation: 527
In a previous question I asked about creating an Applescript for a Bluetooth file exchange. I would now like to (if possible) check whether there is currently an exchange in progress, if so, wait for it to complete before another file is put through, creating a queue of some sort.
With my current code, it will just create an error if you try to put through another file to transfer while one is already in process of transferring, ruining the whole automation process.
My current automation is set-up as follows. I have another automation which detects when a file is added to my camera's sd card, it then renames it to "HP.jpg" and transfers it into the ImagesPrint folder (below), activating this:
After it is moved, it is then renamed using the time so there are no duplicates.
I plan on having multiple images (15-20) dropped into the camera sd folder at the same time and this "queue" to "slow it down" in a way so only one can go through this whole process at a time, so the file transfer is not stuffed up.
Upvotes: 3
Views: 283
Reputation: 6102
I believe I have the means for you to determine whether a Bluetooth file transfer is in progress, or—more usefully—when a Bluetooth file transfer has completed or terminated.
The first part of my answer is a digression, largely because I couldn't get AppleScript on my system to initiate the file transfer through using the send
command of the Bluetooth File Exchange application. I don't know why, and I ran out of patience to diagnose it. So, instead, I used AppleScript GUI scripting to interact directly with the Bluetooth File Exchange application GUI and physically control the file sending process.
(This does, of course, mean I had to manually select the files from a dialog box that pops up, which was fine for my needs.)
I'll include my script here as a reference for anyone else who may be interested, even though it's not relevant to your question. I can't recommend this method particularly, as it's not very robust and AppleScript occasionally throws an error for no particular reason during one run, but then will function completely fine for the next 5 or 6 runs, so it's a bit unstable. I'm running this on MacOS 10.13:
activate application "Bluetooth File Exchange"
tell application "System Events" to tell application process "Bluetooth File Exchange"
tell menu item "Send File…" of menu "File" of menu bar item "File" of menu bar 1 to ¬
perform action "AXPress"
repeat while (exists window "Select File to Send")
end repeat
set W to a reference to (first window whose name begins with "Send")
tell W
set SendButton to button "Send"
set R to a reference to rows of table 1 of scroll area 1
set T to a reference to (static texts of UI element 1 of R whose value is Device)
set U to a reference to value of attribute "AXParent" of T
set [D] to a reference to value of attribute "AXParent" of U
select D
set start_time to do shell script "date +%Y-%m-%d\\ %H:%M:%S"
click SendButton
end tell
(*
repeat while (exists W)
end repeat
(*** File transfer started ***)
set W to a reference to window "Bluetooth File Exchange"
repeat until (exists W)
end repeat
repeat while (exists W)
delay 2
end repeat
(*** File transfer finished ***)
*)
end tell
When one interacts physically with the application in this manner, a progress window appears during file transfer. Purely as an exercise, I incorporated monitoring of this window for its appearance to mark when file transfer had begun; and then again for its disappearance to mark when file transfer had completed. It works well enough, but obviously isn't the solution for your particular case, so the lines are block-commented out in the code above.
After a lot of combing through various log files on my computer, I managed to isolate two useful log entries that get written during a Bluetooth file transfer. As such file transfers will be logged by the system, it provides a reliable method of determining when a Bluetooth file transfer began (or has begun), and when it completed (or completes).
The log data are accessible using the shell command log
, and filtered with specified parameters. Note that the parameters I chose aren't the only ones available, and also aren't the only ones that could be used to determine the start/stop of a Bluetooth file transfer. In different portions of the log, I did notice there were parallel event messages being reported that lined up just as reliably with the ones I eventually settled on. I chose my particular subsystem
and category
because the messages contained in those data were human-readable English, and distinctly unambiguous as to what events were taking place.
I created the relevant shell command and stored it in an AppleScript variable:
set command to "log show --predicate " & ¬
"'(subsystem == \"com.apple.bluetooth\") && (category == \"bluetoothd\")'" & ¬
" --start \"" & start_time & "\" --style json " & ¬
"| grep 'EVENT: Disconnection Complete'"
Then, just before the file transfer was activated (i.e. just before my script clicked the Send
button), I obtained the start date and time of the transfer (as you can see in the script above: set start_time to do shell script ...
), then continuously monitored the log for the appropriate messages appearing after this timestamp that reported the completion of a Bluetooth transfer:
repeat
try
set disconnected to do shell script command
if disconnected contains "EVENT: Disconnection Complete" then ¬
exit repeat
end try
delay 2
end repeat
The message that gets written to the log is a very clear EVENT: Disconnection Complete
, which when read in the full context of its log entry, is reporting the disconnection of bluetooth devices in response to a termination of file transfer (either through success or through failure). I use a grep
command in my do shell script
in order to filter the log entries and isolate only that portion of text.
Therefore, during the repeat
loop above, the do shell script
spends the majority of its time throwing an error (quite rightly) because the absence of this text means grep
is unable to return a value. When the log entry finally appears, grep
finds it and returns it, which allows the repeat
loop to end.
Similarly, there's an event message written to the log when Bluetooth file transfer begins, reporting an OBEX Object Push
, and another at the same time reporting an OBEX File Transfer
. These are pretty definitive markers for the start of a Bluetooth transfer, however I didn't have cause to monitor specifically for these log entries to appear, as the script was in control of determining when the file transfer would commence.
Adding those latter two snippets of AppleScript into your Run AppleScript action would allow you to get rid of the Pause action, as the AppleScript would continue to run—caught in its repeat
loop, until the file transfer has completed.
Firstly, paste this line right before your tell application "Bluetooth File Exchange" to send...
statement:
set start_time to do shell script "date +%Y-%m-%d\\ %H:%M:%S"
Next, paste the rest of the log-monitoring code after the tell application...
statement. So your Run AppleScript action will now look like this:
set MF to (POSIX path of "Macintosh HD:Users:max:Desktop:ImagesPrint:HP.jpg") as string
set Adr_Device to " "
set start_time to do shell script "date +%Y-%m-%d\\ %H:%M:%S"
tell application "Bluetooth File Exchange" to send file MF to device Adr_Device
set command to "log show --predicate " & ¬
"'(subsystem == \"com.apple.bluetooth\") && (category == \"bluetoothd\")'" & ¬
" --start \"" & start_time & "\" --style json " & ¬
"| grep 'EVENT: Disconnection Complete'"
repeat
try
set disconnected to do shell script command
if disconnected contains "EVENT: Disconnection Complete" then ¬
exit repeat
end try
delay 2
end repeat
If you're curious about what the log entries look like in their entirety (but still filtered by subsystem and category), you can examine a JSON-formatted output here, during which two separate Bluetooth file transfers started and completed.
Upvotes: 3