As many are aware, although you can schedule scripts to run with iCal, but iCal does not provide any information about the event that triggered the script, not even if you use Automator to create an iCal alarm workflow; a deficiency that I find infuriating and inexcusable, but one that Apple seems to have no interest in addressing.
The solution that I have implemented searches through events in a specific calendar in iCal (named "Indigo" in this case) to try and find which event occurs closest to the time the script was run. This only works if the event does not trigger the alert before the start time specified in the event. It also assumes that the alert triggers the script to run before any other event takes place in the calendar, or it will return the latter event instead of the one that triggered the script.
This method is also capable of finding repeating events. (If you set an iCal event to repeat, iCal does not actually create those events, it only creates the first event and renders the subsequent time blocks in the calendar view.)
I wrote this script because I don't particularly care for the iCal plugin in Indigo 5.x for the following reasons: controlling Indigo by email is contingent on having functional internet access, which doesn't always happen: router, modem, ISP, mail service, and also hoping that the email comes back within a timely fashion without some weird delivery failure. Second, as the developers clearly state, the email plugin will respond to any email that is formatted for Indigo, and dutifully execute whatever it instructs; sounds dangerous. Finally, I personally think it's silly for a program on computer A to talk to another program on computer A by using computer B (the mail server) as an intermediary.
I have not tested this exhaustively, but so far it has been able to correctly find and extract information from iCal events nestled between other iCal events (subject to the aforementioned constraints). ***Edit: all of the cases I have tested it against are set to dispatch the alert 0 minutes before/after, in the iCal alert settings. If anyone can find cases where it does not work, or how it can be improved, then let us discuss the issues and solutions here to lead to a robust solution to this problem. ***Edit: I would like to keep the core script application-agnostic, but I encourage and welcome any discussion on optimizations or integrating it into other scripts for Indigo (or other applications).
- Code: Select all
-- attempt to find the iCal event that triggered the alarm and extract the data
set eventList to {}
set referenceDate to the current date
-- first, construct a list of events that are not after the current time and date (seperately)
tell application "iCal"
repeat with eventItem in events of calendar "Indigo"
if the start date of eventItem does not come after referenceDate then
set compareTime to the time of the (start date of eventItem as date)
if compareTime does not come after the (time of referenceDate) then
set the end of eventList to eventItem
end if
end if
end repeat
end tell
-- second, find the closest iCal event that occurs at the same time as the alarm was triggered
-- and for whatever reason, I can't get it to work right using repeat with … in …
set bestMatch to item 1 of eventList
repeat with index from 1 to (count eventList)
tell application "iCal"
set compareDate to the start date of item index of eventList
set previousBest to the start date of bestMatch
end tell
if compareDate comes after previousBest then set bestMatch to item index of eventList
end repeat
-- extract the data from the event
tell application "iCal"
set eventSummary to the summary of bestMatch
set eventDescription to the description of bestMatch
set eventStartDate to the start date of bestMatch
set eventEndDate to the end date of bestMatch
end tell
In the case of a repeating event, the start and end dates and times will be of the first chronological instance of that event in iCal. To translate them to today's terms, use the following:
- Code: Select all
-- translate event dates to today
set startDate to the current date
set the time of startDate to the time of eventStartDate
set endDate to the current date
set the time of endDate to the time of eventEndDate
In addition, I have written an entire script that allows one to control devices, scenes and action groups within Indigo by putting instructions in the 'notes' section of the iCal event. It will also turn those devices and scenes off at the end of the event duration. I am still testing and tweaking it, but I will post it in a new thread when it is satisfactory.