Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| developer:applescript_integration_strategies [2018/02/22 18:46] – [Running AppleScripts from Python with py-applescript] jay | developer:applescript_integration_strategies [2024/06/27 00:08] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== AppleScript Integration Strategies ====== | ||
| + | As published in the [[http:// | ||
| + | |||
| + | Note that Indigo will continue to support executing external AppleScripts that do not target the Indigo Server (via a "tell IndigoServer" | ||
| + | ==== Consider Easier Alternatives to Scripts | ||
| + | |||
| + | Many times, AppleScript was used to solve a specific need for your automation due to missing features in Indigo. Over the years, however, Indigo has advanced to accomplish much more. We highly recommend [[https:// | ||
| + | |||
| + | Also, Indigo now has a very comprehensive [[http:// | ||
| + | |||
| + | ==== Converting Indigo AppleScripts to Python ==== | ||
| + | |||
| + | The preferred way of scripting Indigo is to use the Python scripting integration. Python is an easy-to-use but very powerful scripting language. Although the syntax is different than AppleScript, | ||
| + | |||
| + | If you have an AppleScript that you are having difficulty converting, then [[https:// | ||
| + | |||
| + | Also new to Indigo 7.4 is that embedded script conditionals (in Triggers and Schedules) are now Python and not AppleScript, | ||
| + | ==== Running AppleScripts from Python with py-applescript ==== | ||
| + | |||
| + | Converting to Python may not always be possible or desirable and there are alternatives. Turns out there' | ||
| + | |||
| + | === The basics of using py-applescript === | ||
| + | |||
| + | Using the module is very simple. As with any Python module, the first thing you want to do is import it: | ||
| + | |||
| + | import applescript | ||
| + | |||
| + | The next step is to create an AppleScript object. This can be done by loading an AppleScript from a file or by using an embedded AppleScript string. Here are examples of both ways: | ||
| + | |||
| + | import applescript | ||
| + | | ||
| + | # From a file | ||
| + | path_to_script_file = "/ | ||
| + | my_ascript_from_file = applescript.AppleScript(path=path_to_script_file) | ||
| + | | ||
| + | # From an script in a Python string | ||
| + | ascript_string = ''' | ||
| + | say "Hello Python!" | ||
| + | set someDict to {abool: true, afloat: 35.730} | ||
| + | set someList to [1, " | ||
| + | return {anum:1, astring:" | ||
| + | ''' | ||
| + | my_ascript_from_string = applescript.AppleScript(source=ascript_string) | ||
| + | |||
| + | Other than where the script source comes from, these two methods result in an identical Python AppleScript object. The contrived record in the embedded AppleScript string in the example above contains several different value types which are returned. | ||
| + | |||
| + | Finally, running the AppleScript object is quite simple: | ||
| + | |||
| + | reply = my_ascript_from_string.run() | ||
| + | |||
| + | This will execute the run() handler or, if there is none (as in the example), it will just execute the script. The Python reply variable will contain a Pythonic version of whatever is returned from the script. In the example it will be a Python dictionary: | ||
| + | |||
| + | { | ||
| + | u' | ||
| + | u' | ||
| + | u' | ||
| + | u' | ||
| + | } | ||
| + | |||
| + | As you can see, the AppleScript record returned to the Python script has been converted to standard Python objects. | ||
| + | |||
| + | === Calling handlers === | ||
| + | |||
| + | |||
| + | If your AppleScript is complex or contains a lot of related logic, you can implement handlers (AppleScript functions) and then call those specific handlers. Let's say you have the following AppleScript: | ||
| + | |||
| + | on saySomething(speechString) | ||
| + | say speechString | ||
| + | end saySomething | ||
| + | | ||
| + | on getiTunesPlaylists() | ||
| + | tell application " | ||
| + | set myPlaylists to name of every playlist | ||
| + | end tell | ||
| + | return myPlaylists | ||
| + | end getiTunesPlaylists | ||
| + | |||
| + | Note that it contains two handlers. One accepts a string and speaks it, the other doesn' | ||
| + | |||
| + | import applescript | ||
| + | | ||
| + | # From a file | ||
| + | path_to_script_file = "/ | ||
| + | my_ascript_from_file = applescript.AppleScript(path=path_to_script_file) | ||
| + | | ||
| + | # You don't need to set the return value because the handler doesn' | ||
| + | # return anything - it just speaks the string and returns. | ||
| + | my_ascript_from_file.call(" | ||
| + | | ||
| + | # Call the method (it has no params) and assign the reply to the Python | ||
| + | # playlists | ||
| + | playlists = my_ascript_from_file.call(" | ||
| + | |||
| + | At the end of the above script snippit the playlists Python variable will contain a Python list of playlist names from iTunes. | ||
| + | |||
| + | As you can see, you can easily integrate data from Python, such as device state values, variable values, etc., into an AppleScript by passing that data to a handler. You can also just as easily pass back data from an AppleScript to Python and you'll get that data in native Python objects such as unicode strings, numbers, lists, dictionaries, | ||
| + | |||
| + | |||
| + | ==== The Indigo Control AppleScript ==== | ||
| + | |||
| + | In situations where you cannot conveniently and/or securely get the username and password for your Indigo Server or where you cannot run the Indigo Web Server, then you can use the [[https:// | ||
| + | |||
| + | There are a couple of ways to use the script. First, you can just copy/paste the script to where you want to use it then call the handlers you need to at the end of the script. There are examples at the bottom of the script of how to do that. | ||
| + | |||
| + | The other option is to save the script to your hard drive, then have any AppleScript that needs to use it load the script as an AppleScript script object: | ||
| + | |||
| + | set indigo to load script (POSIX file "/ | ||
| + | tell indigo | ||
| + | toggle_byID(" | ||
| + | updateVariable_byID(" | ||
| + | executeActionGroup_byID(" | ||
| + | end tell | ||
| + | |||
| + | ==== Help Converting AppleScript Scripts ==== | ||
| + | |||
| + | We've created a [[https:// | ||