Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Set iChat status according to physical location Apps
There are plenty of scripts to set your iChat status according to what music you're listening to and whatnot. However, since I have a laptop, I find it more useful to set my iChat status message according to where I am at the time (e.g., work, home, cafe down the street). This helps to let people know if it's an appropriate time to message me or not. After a while, I found that I often forgot to change my status accordingly, and I would be advertising that I was at work when I was in fact home or vice-versa. It occurred to me that it was possible to divine this information based on my network connection, so I wrote a daemon script to update my iChat status automatically.

Here's how the script works. Locations can be distinguished by an IP address prefix (subnet), or wireless SSID (the name displayed in the airport menu). The script first checks to see if there is an active wired connection. If so, the status message is set based on a table of names and subnets that the user of the script must create. If there is no wired connection, but wireless is active, the same table is checked for matching subnets and SSIDs. If none are found, then the SSID itself is used. If the script is successful, the iChat status message will be set to "@locationName" for known wired locations, "802.11@locationName" for known wireless locations, and "802.11@SSID" for unknown wireless connections. To help you know its working, the script uses AppleTalk to say "Changing iChat message status" when there is a change.

There are a number of situations that the status message will not be changed:
  • iChat is not running
  • iChat is offline
  • There are no active network connections
  • The script cannot determine an appropriate status message (no entry in table)
  • The current status message is non-generic (Available, Away) and is not in the format used by the script. This is to allow you to set the message to something special (e.g. "At Lunch") and not have the script change it

Here's how to use the script:

  1. Using Script Editor, edit the list of properties at the beginning.
  2. A location can be defined by the ssid and/or subnet fields, but must define a statusMessage field. The subnet field can be a complete IP address if desired, since the script just does substring matching. Make sure to add any new location properties to the localeTable property, or they won't be found.

  3. Edit other properties
  4. Two simple ones are idleTimeout and changePhrase. Making changePhrase "" is an easy way of shutting the script up. It's also relatively straightforward to change the scripts conventions about "802.11" and "@", but if you don't know what you're doing, it may mess things up.

  5. Save the script as an application, making sure to check "Stay Open"

  6. Optionally, use Drop Script Backgrounder to prevent the script from showing an icon in the dock.

    This is a nice way to remove clutter once you're happy with the way the script works, but you'll have to rerun this utility every time you change the script, so keep it around.

  7. Add the script to your startup items (it's not much use if it's not running all the time)
Last, but not least, the source of the script itself -- download it from macosxhints.com: ichatloc.scpt.zip.

[robg adds: I haven't tested the script, but if you travel with your laptop, it could be quite handy. The source was originally included directly with this hint, but due to its length and formatting challenges due to some long lines, I chose to make it a separate download. Jason Snell of Macworld posted a different version in his Macworld Weblog a while back. I haven't compared the two to see how they differ...]
    •    
  • Currently 2.60 / 5
  You rated: 2 / 5 (5 votes cast)
 
[29,114 views]  

Set iChat status according to physical location | 17 comments | Create New Account
Click here to return to the 'Set iChat status according to physical location' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Set iChat status according to physical location
Authored by: crashcane on Apr 15, '04 03:41:06PM
At first, I couldn't get Jon's applescript to work on my iBook (dual USB). The problem seemed to be that it could not get the base station name. So I tried Jason Snell's applescript, and it seemed to be able to identify the connected base station.

The command each script is using to determine the base station is different, with Jon's using ioreg and Jason's using system_profiler.

However, Jason's script doesn't automatically react when you change base-stations, so it has to be run periodically (via cron). So, I started with Jon's script and replaced the code reading:

 set ssid to do shell script "ioreg -n AirPortPCI -S -w 0 | perl -n -e 'print \"$1\\n\" if /\"APCurrentSSID\" = \"(.*)\"/;'"
with the code from Jason's script:
 set ssid to do shell script "system_profiler SPAirPortDataType|awk -F\": \" '/Current Wireless Network/{print $2}'"
Now, I am not sure if this represents the true ssid, but in my situation, it works.

[ Reply to This | # ]
Set iChat status according to physical location
Authored by: jonbauman on Apr 16, '04 08:49:29AM
At first, I couldn't get Jon's applescript to work on my iBook (dual USB). The problem seemed to be that it could not get the base station name.
The command each script is using to determine the base station is different, with Jon's using ioreg and Jason's using system_profiler.

Just out of curiosity, what version of Mac OS are you running and what do you get when you run ioreg -n AirPortPCI -S -w 0? I wrote this script for 10.3.3. I sort of doubt that any difference in perl version would make a difference, but perhaps ioreg's output format has changed. Also the reason I used ioreg instead of system_profiler is because the former runs faster. I did a little test with the time utility. ioreg got

real    0m0.124s
user    0m0.040s
sys     0m0.030s
whereas system_profiler got
real    0m0.801s
user    0m0.160s
sys     0m0.090s
Clearly this is not a real performance issue, but interesting to note. One other thing to mention is that my script would work fine as a cron job executed by osascript rather than as a a stay-open application. The latter just requires more UNIX knowhow.

---

jon

[ Reply to This | # ]

ioreg output on my system
Authored by: crashcane on Apr 16, '04 04:19:18PM
I am using 10.3.3, an apple standard airport(.b) card, and the original Airport basestation.

I don't know a lot about ioreg, but I get the exact same output when I type ioreg -n AirPortPCI -S -w 0 as when I use ioreg -S -w 0. Further, neither of those outputs, nor the output from ioreg -w 0 contain the text "ssid" or "AirPortPCI", which I imagine they do for you. Perhaps it matters what sort of wireless basestation we are connecting to? or something I have misconfigured?

BTW,thanks for sharing your script, as I am really enjoying it.

[ Reply to This | # ]

AirPortPCI vs. AirPortDriver
Authored by: leif on Apr 19, '04 10:01:08PM
On my dual-usb iBook with an (unextreme) AirPort card, there is nothing for AirPortPCI, but there is data for AirPortDriver (you can get the SSID with ioreg -n AirPortDriver|grep APCurrentSSID|cut -d '"' -f 4).

I'd guess you've got 802.11g, or a non-apple 802.11b card ?

[ Reply to This | # ]
Set iChat status according to physical location
Authored by: townsnda on Jul 27, '05 01:33:37PM

ahh hah. changing the set ssid line as per earlier comment

set ssid to do shell script "system_profiler SPAirPortDataType|awk -F\": \" '/Current Wireless Network/{print $2}'"

seems to still work under the new airport driver.



[ Reply to This | # ]
No longer working with new Airport driver?
Authored by: townsnda on Jul 27, '05 01:30:35PM

Has anyone noticed that this script no longer works after the latest Airport driver update?

Seems to be having trouble fetching the current SSID

Not a scripter, so I can't contribute a fix



[ Reply to This | # ]
Set iChat status according to physical location
Authored by: imagine on Apr 15, '04 05:35:16PM
A motivated developer should read this paper and think about how they want to apply it to Mac OS X. - Josh

[ Reply to This | # ]
Set iChat status according to physical location
Authored by: xtian on Apr 15, '04 07:03:03PM

How about a script that will look at my iCal calendar and sets my status depending on the current event in? That would be very cool.



[ Reply to This | # ]
Set iChat status according to physical location
Authored by: jonbauman on Apr 16, '04 09:13:44AM

This would be way easier if iCal offered anything in the way of actually useful AppleScript commands. For instance, it would be trivial if there were a command that you could pass a date object, and get a list of corresponding events back. The way things are currently, all you can get is a list of all the events belonging to a given calendar. The script would have to deduce based on start and end times and repeat types whether that event was currently occurring. I'm going to poke around with it a bit and see how tricky it is.

---

jon

[ Reply to This | # ]

Set iChat status according to physical location
Authored by: jsnell on Apr 16, '04 03:47:40PM
An interesting variation on my piece. For the record, my script doesn't require cron... I actually have taken to using Script Software's Scenario, which executes the script only upon wake from sleep and startup. Since those are usually the times when I switch SSIDs, it works for me. I'm not a big fan of keeping scripts running all the time, either.

---
Jason Snell, Editor, Macworld

[ Reply to This | # ]

Set iChat status according to physical location
Authored by: moliu on Apr 19, '04 04:57:15AM

actually, I can't get your script to work with cron. I'm using cronnix to run the script. Here's the problem. I saved the script in my doc folder.
I've tried to add the script to the cronnix directly. Nothing happens when it's suppose to run. So I tried to save it as an application with the run only option.
When I double click on the program to run, it runs perfectly. However if it was cronnix running the program as scheduled, it doesn't do anything...

Am I doing something wrong? Do I have to use the prepend "/usr/bin/open" option?

Thanks for you help!



[ Reply to This | # ]
Set iChat status according to physical location
Authored by: jonbauman on Apr 19, '04 11:52:27AM

There are two options if you want to use cron or some other utility to periodically execute the script. Either you can save the script as an application with the Stay Open option not checked, or you can save it as a script. There's no need to check Run Only in either case. That just hides the source and makes the script uneditable. If you save as an application, you can run the script with /usr/bin/open /path/to/application and for the script version, use /usr/bin/osascript /path/to/script.

---

jon

[ Reply to This | # ]

Set iChat status according to physical location
Authored by: StarManta on Apr 23, '04 01:42:04PM
I modified the script to work with iChatStatus, a freeware PrefPane app. So it's basically the same thing, only a little less trouble to set up if you already have iChatStatus installed. This also has the changes that crashcane pointed out (since they worked for me), if the script does not work, try reversing his change.

property UC : {ssid:"NoWireUC", subnet:"129.137.164", statusMessage:"@UC"}
--insert your locales here, as modeled in the original script... the rest of mine removed for privacy reasons
property localeTable : {UC}
property idleTimeout : 60 -- seconds

on getLocation()
	set wiredIP to do shell script "ifconfig en0 | awk '/inet / {print $2}'"
	set wirelessIP to ""
	set ssid to ""
	set connected to false
	set wired to false
	set IPAddress to ""
	
	if wiredIP is not "" then
		set IPAddress to wiredIP
		set connected to true
		set wired to true
	else
		set wirelessIP to do shell script "ifconfig en1 | awk '/inet / {print $2}'"
		
		if wirelessIP is not "" then
			set IPAddress to wirelessIP
			set ssid to do shell script "system_profiler SPAirPortDataType|awk -F\": \" '/Current Wireless Network/{print $2}'"
			set connected to true
			set wired to false
		end if
	end if
	return {connected:connected, wired:wired, IPAddress:IPAddress, ssid:ssid}
end getLocation

on debug(phrase)
	--say phrase
end debug

on setStatus()
	set currentLocation to my getLocation()
	
	if wired of currentLocation then -- set based on IP
		repeat with locale in localeTable
			try -- locale may not have subnet field
				if IPAddress of currentLocation begins with subnet of locale then
					return my changeStatusTo(statusMessage of locale)
				end if
			end try
		end repeat
	else -- we must have wireless, since connected is true
		
		repeat with locale in localeTable
			try -- locale may not have subnet field
				if IPAddress of currentLocation begins with subnet of locale then
					return my changeStatusTo("802.11" & statusMessage of locale)
				end if
			end try
		end repeat
		
		-- no IP matches, check SSID
		
		if ssid of currentLocation is "" then -- should never happen
			return ("Wireless connection, but no SSID")
		end if
		
		repeat with locale in localeTable
			try -- locale may not have SSID field
				if ssid of currentLocation is ssid of locale then
					return ("802.11" & statusMessage of locale)
				end if
			end try
		end repeat
		
		-- no matches in table, just set to SSID
		return ("802.11@" & ssid of currentLocation)
	end if
	
	
end setStatus


my setStatus()




[ Reply to This | # ]
Set iChat status according to physical location
Authored by: jonbauman on Apr 27, '04 12:35:39PM
I'm not a big fan of keeping scripts running all the time, either.

After using my own script this way for awhile, I've decided that I'm not a big fan of it either. For no reason that I could determine, it just seemed to stop executing the idle loop after running for a couple of days. It's no problem though, the same script runs like a dream with cron. For those of you who don't feel like digging through man pages, here's how to set it up.

  1. Make sure your EDITOR environment variable is set to something you can use. For me this is emacs. Under bash a command like export EDITOR=`which applicationName` will do the trick.
  2. run crontab -e to edit your user-specific crontab file.
  3. To the first line of the file, add PATH=/bin:/sbin:/usr/bin:/usr/sbin. This is so the commands in the script like perl, ioreg and ifconfig can be executed without specifying their full paths, but it's a nice thing to have in your crontab in general.
  4. Add this line: * * * * * /usr/bin/osascript "/path/to/script" >& /dev/null
  5. Save your changes and quit your editor. Unless you messed up, you should see the message: crontab: installing new crontab.

This setup will run the script once a minute, which I think is reasonable. If you want to make it run less often, you can replace the first asterisk with "*/N" to make it run every N minutes. For a full explanation of the crontab file format run man 5 crontab.

---

jon

[ Reply to This | # ]

Set iChat status according to physical location
Authored by: schalliol on Aug 30, '04 03:12:56AM

This is a great script. Thanks very much, as well to those making additions. I love the ichatstatus implementation, I couldn't get the original cron to work.

I do have one thing I'd like to do if you think it could be done: I have 4 wireless access points on my site, but they all have the same SSID so that active roaming can be done seemlessly. Is there any way that one could figure out which is which and then allow me to display which area of the location I am in? I'm thinking perhaps there could be something around sensing the MAC address of the access point, any ideas?



[ Reply to This | # ]
Set iChat status according to physical location
Authored by: babbletower on Dec 01, '05 07:49:34PM

Just made a "one-liner" that shows the domain I'm are at:

[code]
on idle
tell application "iChat"
set status message to do shell script "/Applications/lynx.command -dump http://www.whatismyip.com | grep Your | awk '{print $4}' | nslookup -silent | grep 'name =' | awk 'BEGIN {FS="."} ; {print "I\047m at "$7"."$8"."$9"."$10}'"
end tell
return 60
end idle
[/code]

Downside is that I depend on Lynx and the whatismyip.com. Lynx can easily be downloaded and there will always be a service similar to whatismyip.com out there, but there must be a simple way to do the same with pure local unix means. Any ideas?

Bo



[ Reply to This | # ]
Set iChat status according to physical location
Authored by: babbletower on Dec 02, '05 12:12:49PM

oh, I just noted that the posted code is missing backshlashes in front of all the quotes (exept the appletalk quotes). Also two backslashed and a xero is missing in front of my 47 (apostrophe) rendering.

I also discovered that I made a little error. I'm printing 7, 8, 9, 10, that should have been 6, 7, 8, 9. So this version doesn't get the precise node that you are on, which might actually be good securitywise... if you want the correct output you should take 6, 7, 8, 9 and remove the arpa name = ... with a awk print dollar 4... you figure is out.

Bo



[ Reply to This | # ]