Cool phone tricks

One of the things I “lost” when I shutdown my server and stopped running my Asterisk PBX was the ability to redirect calls to my phone to my computer in case I was out of town or the like. When we travelled back east last month, we stayed with my uncle who had really high speed Internet (Verizon FIOS), but had virtually no cell phone coverage (neither my Sprint PCS nor my AT&T phone could keep a connection). One day I had to take a business call, but didn’t want to hog my uncle’s phone line, so I re-directed my PBX to send my calls over SIP to my Mac (using the Gizmo Project’s SIP client). That was pretty cool, but I can no longer do that.

I’ve had a GrandCentral account for awhile and had read about forwarding to a Gizmo Project account. Today, I decided to play around and low and behold, I can still get work calls on my computer by having people call my GrandCentral number (which I’m now going to start giving out as my work number). Furthermore, I can make outgoing calls by adding people to my GrandCentral phone book and originating the call through the GrandCentral website (Gizmo Project charges for outgoing, but not incoming calls; this method makes the outgoing call actually an incoming call). So not only can I receive calls on my computer, I can now make free calls! I don’t need free calls as I have unlimited long distance on my home phone, I have 100 outgoing minutes per month on my work line, and more than enough minutes on my cell phones. I don’t even talk on the phone all that much!

Broken Idle Time in 10.4/10.5

After fighting with trying to get the amount of time since a user has done something with the system, I’ve determined that CGEventSourceSecondsSinceLastEventType is broken. The documentation indicates that calling it like:

CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType)

will tell me how many seconds since the user last moved the mouse, touched the keyboard, etc. The docs say:

The various system and app defined events do not contribute to this event type’s time.

Unfortunately this just isn’t true. In one app I’m working on, I have a timer that fires every 5 seconds and prints the idle time. It starts going up, but then a notification comes in and it resets back to zero without me touching the keyboard. So, this call is almost useless as I need to know when things are idle in order to perform some tasks. While some of you are saying that I can use a Carbon Event Idle Timer, it turns out that they don’t work in background only apps. My only solution is to make the above call using something like:

+ (double) idleTimeInSeconds
{
	double idleTime = 0;
	double tempIdleTime = 0;
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventMouseMoved);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseDragged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseDragged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventKeyDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventKeyUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventFlagsChanged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventScrollWheel);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventTabletPointer);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventTabletProximity);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}
	
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseDragged);
	
	return idleTime;
}

Wow, that is freaking ugly, but at least I know exactly when a user event occurred. Feel free to use my code in any way you see fit. I've searched the web and found answers to a lot of my problems, so here's a small contribution back to the community.

Thanks for the update, Fujitsu!

When Leopard came out, I blogged about a bug in Fujitsu’s ScanSnap Manager software. I was unable to get anywhere with Fujitsu and almost forgot about it. However, today in trolling through their website, I saw that they had an article specifically about the software running under Leopard along with a download to a new version of the ScanSnap Manager. Yeah, I downloaded the software, gave it a try and found that it fixed my problem. However, they added a stupid feature called “Quick Menu” which brings up a half baked feature allowing you to send stuff to email, a folder, iPhoto, etc.

Too bad Fujitsu has never heard of VersionTracker or MacUpdate to post updates so that customers can actually find out about updates without having to dig through their site (which actually doesn’t have a direct link to the Mac software under their downloads area).

ATMs attempting to be intelligent

Bank of America installed new ATMs sometime this year which, for the most part, are pretty user friendly. They’re touch screen based (along with a physical keypad) and automatically scan in checks. You have to insert the check in the correct direction or the ATM spits it out because it can’t OCR the check. While OCR does take time, it would seem that the ATM could simply flip the image and try the OCR again instead of spitting it out. This isn’t rocket science to add that code:

if (!OCRsuccess)
{
	rotate image;
	do_ocr;
}

It would have saved the bank lots of money on printing “insert check this way” labels.

Quality HP Software

For years I’ve complained to my father about the poor quality of HP’s Mac scanner software. He always brushed it off as my standard are pretty high and it would appear (to outsiders) that I don’t like many programs. (There are some programs I really like and there are some that just suck; yes, my standards are high, but I’m on a Mac and I deserve the best!). Recently, he started using his HP All-In-One with his new Mac (he had been using it from his PC) and after hours (maybe days) of frustration, he contacted their support and got no where (support was on a PC reading from a script). He complained up the change and accused them of fraud/deception as they advertised certain features working on the Mac, when they clearly don’t.

It was quite fun basically saying “I told you so”; I have an HP All-In-One that I bought several years ago that I only use as a fax machine and a copier; for those functions, it works great. If HP is serious about the Mac, they need to step up to the plate and re-write their software. Windows users might like the cutesy scanning app, but Mac users just want it to work like every other Mac application and integrate with Address Book (for the fax app), etc.

If their devices weren’t so cheap, Mac users probably wouldn’t be lured into buying them.

Turned off my server

As I’ve previously written, I started making the move to turn off some of the services running on my server. Last week, I managed to move the last service (SlimServer) running on my server somewhere else; in this case to my AppleTV which is quieter and more energy efficient than my monster server. So, last Monday, I sent an init 0 to the server and turned it off. I then moved my UPS to my office. It is such a relief to no longer have to make sure my server is running; while I do have some services running on my virtual private server, I don’t have to worry about it physically being up. In addition, by not using my server as a router, I don’t have to worry about restarting my server and having it affect my internet connection.

Things have been humming along and Google for Domains is working out quite well. With GoDaddy handling DNS and email forwarding on some domains, I don’t see a need for me to turn on my server. It has been a great experiment and has taught me a lot; I first brought a dedicated server online something like 8 years ago!

Radio Hanukkah == Radio Not-Christmas

The other day I heard an ad (yes, an ad) on XM for Radio Hanukkah. Cool, I thought, and tried to tune it in. After a few false starts (I kept getting a message that I wasn’t authorized to play the stream and then online streaming stopped completely), I was able to tune it in. We started listening to it while lighting the candles and thought it was cool to have Hanukkah tunes, but unfortunately there isn’t enough Hanukkah music to fill a full station. XM Radio has decided to play all music that is Jewish, like “Going to Israel”, “Eliyahu Hanavi”, etc.

There are some pretty funny songs like a Hanukkah song to the tune of an Outkast song. I haven’t heard Adam Sandler’s Hanukkah songs, yet; they’re always a crack up.

Oh well, at least I don’t have to listen to endless repeats of Rudolph the Red Nosed Reindeer.

GPS Search continued

So today I saw that Staples had the Navigon 2100 for $149 and I had a 12% off coupon bringing it to 132. So, I decided to give it a try as it is a bit cheaper than the Garmin units. I was surprised that Staples had it, so I bought it. It came with free lifetime traffic alerts which was a pleasant surprise. After using it for about 5 minutes, I’ve decided that the unit is a piece of crap. First off, I crashed it by ejecting the SD card, second the navigation is awkward, third the unit is very slow when tapping anything, fourth, the POI database with over a million POIs is quite small. It couldn’t find the local Costco that has been there 7 years. Overall, I was quite disappointed with this and will be taking the unit back tomorrow.

However, it reaffirms my research that the nüvi is the unit to get. I should have taken it as a warning that the Navigon website lists that it is running Windows CE. Frankly I don’t care what it runs as long as it runs well. It has a 400 MHz processor in it and it seemed slow as molasses in January (of course, somewhere cold).

Oh well, I’ll just bite the bullet and buy the nüvi.

In search of a new GPS unit

About a week and a half ago, I pulled out my trusty Garmin iQue 3600 to find out the exit for a mall to check out some sunglasses. Well, I managed to not seat the unit properly in the cradle in my car, so it reset itself and wiped out the contents of its memory. That’s the major problem with older Palm OS based devices (one reason I recommended that Qualcomm not use the Palm OS for the pdQ smartphone; losing all your data when the battery dies really sucks). I got royally annoyed at the device and since have been on a quest for a new (modern) portable GPS unit to replace it.

On black Friday, I dragged my wife to the store in hopes of getting a cheap unit. Of course, that didn’t work out. So, I’ve been doing my research on devices. Most GPS units sold come with a suction cup mount that adheres to the windshield. As I was looking at Costco’s website, I discovered that these types of mounts are illegal in California. Yes, I realize that most people either don’t know about it or don’t care. I, however, do my best to adhere to the law. In that light, it appears that the Garmin devices are the only ones that have an optional bean bag portable mount (my iQue has this). So, I’ve narrowed down my search to either the nüvi 260 or the nüvi 360 with the bean bag mount.

However, I don’t need a GPS unit at the moment. My father dropped his iQue 3600 and it no longer charges, so I offered him mine as I don’t use the Palm functionality like he does; he won’t pay me for it (I’m a nice son, aren’t I?), so a new GPS unit will cost me over $300. Most of the time we go somewhere new, we drive my wife’s car which has a built in navigation system, so maybe I’ll just wait until after the new year when maybe there will be rebates or reduced prices.

The Roomba Saga

I finally got tired of the dog hair around our house, so I decided to purchase a Roomba. I purchased the Roomba 560 as it had a number of features that I liked and with the 20% off coupon at Linens N Things, it was $280. At the same time, they had the Scooba 5800 on sale for $250 and with the 20% off coupon, it was $200. I was pleased that we had a chance at clean floors; nether my wife nor I like to clean, but like to have the house clean which creates a problem.The Roomba started making funny noises and the Scooba stopped charging, so I took them back and exchanged them. The next set worked better, but I soon learned that the virtual walls of the Roomba 560 were not compatible with the Scooba, so I’d have to buy extra walls for BOTH devices as we have a large area that I need to clean in sections. Even if cost were not an object (extra virtual walls are about $30 a piece), having 2 sets was not realistic.So, I returned the Roomba and ordered the Roomba 416 direct from iRobot as it was $200 + tax with free shipping (Linens N Things had it for $200 – 20%). iRobot had a special where I’d get a free accessory kit that included 6 replacement filters, a set of replacement brushes, a remote control and another virtual wall. This time, however, the virtual walls of the Roomba and Scooba could be interchanged. The Roomba arrived today and while I didn’t get the remote control, I did end up with an extra virtual wall. So, I now have 5 virtual walls that work with both devices. I like the Scooba and it is doing a decent job; the Roomba seemed to do an acceptable job, but unlike the 500 series, it really bangs into walls. I’ll keep putting both devices through their paces and hopefully I’ll be pleased with my purchase.