Accessing sound volume level etc. on the menu bar

I’m trying to write a script that would change sound volume level and/or display resolution etc. using the items to the right on the menu bar. I know how to access normal menus, such as e.g. File, Edit etc. for a process either by name or number. However I cannot find how to access the special items at the far right on the menu bar. When I specify a number, counting Apple as 1, it says “invalid index”. When I try using a name such as “volumecontrol” it says that it cannot get it.

Another but related question “ how do I specify menu bar without specifying process? I don’t know what process will be in the foreground when the script is supposed to run.

Any comments and/or advice would be greatly appreciated.

Thanks/Mikael

Hi Mikael,

some functions like the sound volume level are directly accessible with AppleScript

set volume number ¬
output volume integer ¬
input volume integer ¬
alert volume integer ¬
output muted boolean

The menu items at the right side belong to SystemUIServer, and these are very tricky scriptable,
here an example to run the menu item “Sync Now” of the sync menu


tell application "System Events"
	tell process "SystemUIServer"
		repeat with mni in (get menu bar items of menu bar 1)
			if (value of attribute "AXDescription" of mni as string) is "" then
				perform action "AXPress" of mni
				set NameList to name of menu items of menu of mni
				if item 1 of item 1 of NameList begins with "Last .Mac" then
					perform action "AXPress" of menu item "Sync Now" of menu of mni
					exit repeat
				end if
			end if
		end repeat
	end tell
end tell

If you have the Sound and Display icons already in your menubar, you can do everything you ask without AppleScript.
If you don’t have those icons in your menubar, go to their respective panes in System Preferences and click “Show Icon in Menubar”.

@Stefan
Many thanks Stefan! Controlling volume using menu bar was mostly an exercise before the real thing which is changing resolution and mirroring (among other things). But even the volume using set volume may come handy when automating a set up for a particular user task. I adapted your script to set resolution to 1680x1050:


tell application "System Events"
	tell process "SystemUIServer"
		repeat with mbi in menu bar items of menu bar 1
			if value of attribute "AXDescription" of mbi as string is "displays" then
				click mbi
				repeat with mi in menu items of menu of mbi
					try
						set miname to name of mi as string
						if word 1 of miname is "1680" then
							if word 3 of miname is "1050" then
								click mi
								exit repeat
							end if
						end if
						error
						-- less than 3 words in miname
						-- do nothing
					end try
				end repeat
				exit repeat
			end if
		end repeat
	end tell
end tell

The crux was process “SystemUIServer” and attribute “AXDescription” as you exemplified. The rest is plain vanilla (after you adapt your vocabulary from Java and C++ to AppleScript).

The next step is to figure out how to execute such a script before a particular application starts and then execute another script when that app ends or perhaps to start execution using a remote control. The app is this case FR.

@Harry
Yes, of course, there are Sound Volume and Displays items in the menu bar; otherwise you cannot get references to them. Yes, of course, you can control them manually by hand. The purpose of a script is to automate a longer sequence of user actions - a sequence that always is to be performed before a particular task. So that the user can focus on the task at hand instead of all the clicking and mousing around required before he/she begins the actual task.

Many thanks again/Mikael

On a related point, I’ve done a script to turn bluetooth on and connect to the net using my bluetooth enabled mobile phone, and another script to disconnect and turn off bluetooth.

With those now in place, the only thing I need is the fact that the modem status menu item shows how long I’ve been connected, which is useful so I don’t stay connected too long for financial reasons. Is there any way I can automate the showing of the modem status menu and make it hide too? I ask as it’s an option in the network preference pane which I’ve already managed to script a bit of.

The alternative would perhaps be a growl status which showed the time connected, maybe every 5 minutes, but that’s way beyond me…:rolleyes:

Any help gratefully received.

Dave

I haven’t been using Bluetooth in this way (yet) so could you clarify it to me please. What would you do manually in order to achieve what you want to achieve? Starting from that sequence of manual actions it should be possible to design a script.

Thanks/Mikael

Yeah, I should perhaps have been more clear.

Now I can automate connecting to the net, I don’t need the Modem Status Menu Extra for any other reason than to show the time I’ve been connected. When I’m not online, I don’t need the menu extra at all, and would like to have shot of it.

So, what I’d like to do is have a script which makes the modem status menu extra visible, and then can turn it off later. If it was something I’d be doing normally, I’d go to the network prefpane, and select ‘show modem status in menu bar’.

HTH,

dave

Well then, this is what your script has to do. Here is one example that I found on the net (it changes energy saver prefs):


tell application "System Preferences"
  activate
end tell

tell application "System Events"
  tell process "System Preferences"
    set frontmost to true
    click menu item "Energy Saver" of menu "View" of menu bar 1
    tell window "Energy Saver"
      -- click the "Options" tab
      -- choose "highest" from the processor performance menu
    end tell
  end tell
end tell

I hope this helps.

Thanks/Mikael