Toggle Bluetooth AppleScript no funciona en Yosemite

Antes de actualizar a Yosemite, usé Keyboard Maestro para invocar este Applescript con un atajo:

tell application "System Preferences"
    reveal pane "com.apple.preferences.Bluetooth"
end tell
tell application "System Events" to tell process "System Preferences"
    click button 6 of window 1
end tell
quit application "System Preferences"

Se comportó tal como se esperaba, alternando bluetooth cada vez que presionaba mi atajo.

Sin embargo, ya no funciona con Yosemite, estoy seguro de que tiene algo que ver con que Apple cambie el panel de Preferencias del sistema o el orden de los íconos, pero no estoy seguro de qué cambiar. El atajo de Keyboard Maestro está invocando el archivo, porque escucho el sonido que le asigné, por lo que definitivamente es algo con el script.

Esto es lo que obtengo en "Respuestas" cuando ejecuto esto en el Editor de secuencias de comandos de Apple:

tell application "System Preferences"
    reveal pane "com.apple.preferences.Bluetooth"
        --> missing value
end tell
tell application "System Events"
    click button 6 of window 1 of process "System Preferences"
        --> button 6 of window "Bluetooth" of application process "System Preferences"
end tell
tell application "Script Editor"
    quit
end tell

Actualizaciones:

Definitivamente no es el panel lo que está causando el problema. Para depurar, cambié el código a:

tell application "System Preferences"
    set current pane to pane id "com.apple.preferences.bluetooth"
end tell

Y abre correctamente el panel de Bluetooth. Ahora todo lo que queda es averiguar qué tipo de acción quiero ejecutar en este panel:

ingrese la descripción de la imagen aquí

Actualización sobre soluciones: ¡Gracias más lejos! Las soluciones de markhunte y fartheraway funcionaron para mí, pero elegí la última porque era más similar a mi código. Supongo que no puedes elegir dos "mejores" respuestas. Desearía que hubiera una solución para que funcione sin abrir el panel de preferencias (visualmente) como lo hizo mi script con Mavericks, pero estos dos deberían ser lo suficientemente buenos.

¿Intentaste reasignar el acceso directo?
No, y también actualicé mi pregunta con esto: "El atajo en sí está invocando el archivo, porque escucho el sonido que le asigné, por lo que definitivamente es algo con el script".
¡Acabo de probar su script (parte 1) en mis Mavericks y obtuve el mismo error (valor faltante)! ¡Así que no es Yosemite!
Bueno, obviamente obtuviste el mismo resultado porque algo cambió en Yosemite: el nombre o la referencia del panel, o el índice del botón en el que se debe hacer clic. Simplemente no puedo averiguar cuál.
¡NO tengo Yosemite! Usé su secuencia de comandos en mi Mavericks (10.9.5) con el mismo problema. No funciona en mis Mavericks.
De nada. ¿Quizás cambiando el título a "¿Cómo activar/desactivar Bluetooth con acceso directo y con el icono de la barra de menú oculto?" podría ser más útil para otros que buscan una solución. Por cierto, esto podría haber sido mucho más fácil si jugáramos con la barra de menús en lugar de SysPref.

Respuestas (6)

Respuesta actualizada/mejor:

1) Este nuevo script no parpadea.

2) Por razones desconocidas para el hombre y la lógica (o solo para mí), applescript a veces/casi siempre falla al desactivar Bluetooth , si la ventana de preferencias del sistema está en segundo plano. En lugar de apagarse, lo que realmente ocurre es que Bluetooth se vuelve a habilitar inmediatamente, por lo que el panel está en un estado nuevo : está ENCENDIDO, pero sin conexiones.

Para superar eso, una forma de traer SysPref al frente, como en la respuesta original. O ejecute un ciclo que haga clic en el botón nuevamente (o por tercera vez) hasta que Bluetooth esté realmente apagado. Por eso hay dos variables y un bucle en el script. Esto debería hacer que el script sea más confiable. statNamevariable registra el estado original. Loopcontinuará haciendo clic en el botón hasta que el estado cambie. failSafese asegura de que el script no se ejecutará para siempre en caso de error. Todo a costa de la estética del código.

tell application "System Events"

    tell process "System Preferences"
        activate
    end tell

    tell application "System Preferences"
        set current pane to pane "com.apple.preferences.Bluetooth"
    end tell

    tell process "System Preferences"

        set statName to name of button 3 of window 1 as string
        set failSafe to 0

        repeat until statName is not name of button 3 of window 1 as string ¬
            or failSafe is 10
            click button 3 of window 1
            set failSafe to failSafe + 1
            delay 0.1
        end repeat

    end tell

    tell application "System Preferences"
        quit
    end tell

end tell

Respuesta original:

tell application "System Preferences"
    activate --Change 1/2
    reveal pane "com.apple.preferences.Bluetooth"
end tell
tell application "System Events" to tell process "System Preferences"
    click button 3 of window 1 --Change 2/2
end tell
quit application "System Preferences"

Desde el Inspector de Accesibilidad :

ingrese la descripción de la imagen aquí

button 3en el elemento número 6 de la lista. El sexto botón es el número 11 en la lista. Cuando llamas button 6a la Ventana de Preferencias, pasa a Genie. Supongo que Mavericks tenía todos los botones amontonados en la parte delantera.

como conseguiste la lista?
Gracias, pero esto solo funciona una vez . Activará Bluetooth al iniciar sesión cuando ejecute el archivo, pero no lo apagará, ni lo encenderá después de que lo encienda manualmente.
Gracias. ¿Hay alguna forma de hacer que funcione sin mostrar el panel de Preferencias?
Hmm, me pregunto por qué funcionó con Mavericks entonces. De todos modos, modifique su respuesta con el comentario activado para que pueda votarlo y elegirlo como "mejor".
Veo que ha agregado —cambio 1/2 y 2/2 allí, ¿es algo que también debería tener? Supongo que es solo para que las personas sepan dónde realizó los cambios, pero puede ser confuso para otras personas que simplemente copiarán y pegarán la respuesta.

He aprendido mucho aquí, ¡espero que esta contribución también ayude a alguien! Descubrí que usar "iniciar" en lugar de "activar" abrirá la aplicación visiblemente, pero no como la ventana de primer plano. El otro truco, o al menos "algo bueno que aprendí recientemente era posible", es usar un ciclo de repetición vacío para esperar a que se cargue la ventana (y que exista el botón) en lugar de un valor de "retraso", que también uso para verificar que el cambio funcionó antes de mostrar una notificación. El resto de mi código se trata de retener el estado de Preferencia del sistema si ya estaba abierto, o salir de él, de lo contrario.

    set bundleID to "com.apple.systempreferences"

-- Check for System Preferences running already
tell the application "System Events" to set runningApps to (bundle identifier of every application process)
if bundleID is in runningApps then
    set stayOpen to true
else
    set stayOpen to false
end if

tell application id "com.apple.systempreferences"
    -- Problem with this setting is that the toggle doesn't work if the prefPane is open in the background — the window /must/ be visible
    if not (stayOpen) then launch

    -- If it's already running, save the current prefPane for later
    if (stayOpen) then set prevPane to current pane

    set current pane to pane id "com.apple.preferences.bluetooth"
end tell

tell the application "System Events"
    -- An empty repeat loop to keep checking for the window
    -- Here I am lazy and don't use the identifier
    repeat until window "Bluetooth" of process "System Preferences" exists
    end repeat

    tell window "Bluetooth" of process "System Preferences"
        if button "Turn Bluetooth Off" exists then
            -- Click and wait for it to change, then send a notification
            click button "Turn Bluetooth Off"
            repeat until button "Turn Bluetooth On" exists
            end repeat
            display notification "Bluetooth Off"
        else
            click button "Turn Bluetooth On"
            repeat until button "Turn Bluetooth Off" exists
            end repeat
            display notification "Bluetooth On"
        end if
    end tell

end tell

tell application id "com.apple.systempreferences"
    if (stayOpen) then
        if prevPane is not missing value then set current pane to prevPane
    else if not (stayOpen) then
        quit
    end if
end tell

Activación o desactivación simple que no necesita verificar el estado primero.

property thePane : "com.apple.preferences.bluetooth"

tell application "System Preferences"
    activate
    set the current pane to pane id thePane
    --delay 1
end tell

tell application "System Events"
    tell application process "System Preferences"
        try
            click button "Turn Bluetooth Off" of window "Bluetooth"
        on error
            click button "Turn Bluetooth On" of window "Bluetooth"
        end try
    end tell
end tell

tell application "System Preferences" to quit
Gracias, este funciona para alternar. Pero a diferencia del script anterior, que no mostraba las preferencias del sistema en absoluto, este deja el panel de Bluetooth visible al final del proceso.
@zerohedge agregó la llamada para dejar de fumar. También puede eliminar el retraso si no lo necesita.

Aquí está mi respuesta:

tell application "System Preferences"
    reveal pane id "com.apple.preferences.Bluetooth"
    -- activate

    set the current pane to pane id "com.apple.preferences.Bluetooth"

    try
        tell application "System Events" to tell process "System Preferences"
            click button "Turn Bluetooth Off" of window "Bluetooth"

            click button "Turn Bluetooth Off" of sheet 1 of window "Bluetooth" of application process "System Preferences" of application "System Events"
        end tell

        delay 1

    on error
        tell application "System Events" to tell process "System Preferences"
            click button "Turn Bluetooth On" of window "Bluetooth"
            quit
        end tell

    end try

end tell

Aquí hay una secuencia de comandos de Bluetooth de alternancia simple que usa blueutil (disponible a través de Homebrew), sin secuencias de comandos de interfaz de usuario. Ajuste la blueutilvariable según sea necesario para que apunte al blueutilbinario si no está instalando a través de Homebrew. Esto se basa libremente en un antiguo script que tenía por ahí que incluía notificaciones de Growl y probablemente era originalmente de http://macosxhints.com (RIP).

set blueutil to "/usr/local/bin/blueutil"
set powerStatus to do shell script blueutil & " power"

if powerStatus is "1" then
    do shell script blueutil & " power 0"
else if powerStatus is "0" then
    do shell script blueutil & " power 1"
end if

Solución AppleScript

Pasos

  1. Abra Automater.app .
  2. Escriba Ejecutar AppleScript en la barra de búsqueda y seleccione para abrir una nueva ventana de secuencia de comandos.
  3. Establezca el Flujo de trabajo recibe en no input la any application configuración en la parte superior de la pantalla.
  4. Copie y pegue los scripts a continuación y guarde el archivo.
  5. Cree un atajo de teclado: Preferencias del sistema > Teclado > Atajos > Servicios > El nuevo script se muestra en General bajo el nombre guardado. > Establecer un acceso directo.

macOS Big Sur 11.5

Flujo de trabajo de alternancia de Bluetooth

tell application "System Events"
    tell process "ControlCenter"
        set BluetoothButton to menu bar item "Bluetooth" of menu bar 1
        click BluetoothButton
        delay 1
        set OnSwitch to checkbox "Bluetooth" of group 1 of window "Control Center"
        click OnSwitch
    end tell
    key code 53
end tell

Consulte: Configuración de Bluetooth con AppleScript en Big Sur - r/applescript, 1/12/20

macOS Monterrey 12.0.1

Flujo de trabajo de alternancia de Bluetooth

tell application "System Events"
    tell application process "Control Center"
        click menu bar item "Bluetooth" of menu bar 1
        tell window "Control Center"
            try
                click checkbox "Bluetooth"
            on error
                click checkbox "Bluetooth"
            end try
        end tell
    end tell
    key code 53 -- # escape key
end tell

Consulte: Error de AppleScript: no se puede obtener el grupo 1 de la ventana "Centro de control" - StackExchange, 10/11/21

Tercero

Para macOS Big Sur, la respuesta de Enrique Scherer ya no funciona. Sin embargo, la utilidad blueutil se ha actualizado y se puede instalar, por ejemplo, desde homebrew.