Help writing small app to sense power outage - newbie

Good morning everyone. I’m new to coding in the Cocoa environment with Applescript. I’ve been working in Applescript Studio. I’m looking for some coding assistance in what hold be a simple app.

The simple Applescript is a repeat loop that runs constantly checking the power source, if the power source becomes the battery on my Macbook Pro, I should get and email and SMS message. The Applescript works perfect.

Now, I want to put this into the new Cocoa programming model and step away from Applescript Studio. Here is the script:

repeat
	set PowerSource to (do shell script "pmset -g ps")
	
	delay 10
	
	if PowerSource does not contain "AC Power" then
		
		set recipientRyanEmail to "myemail@mac.com"
		set recipientRyanSMS to "myphonenumber@txt.att.net"
		set recipientRyanName to "Ryan"
		set theSubject to "POWER ALERT!"
		set theContent to return & return & "Battery Power!"
		try
			tell application "Mail"
				--Create the message
				set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:false}
				--Set a recipient
				tell theMessage
					make new to recipient with properties {name:recipientRyanName, address:recipientRyanEmail}
					make new to recipient with properties {name:recipientRyanName, address:recipientRyanSMS}
					--Send the Message
					send
					
				end tell
			end tell
		end try
		
	end if
end repeat

Can anyone give me some tips on how to get started? I envision the IB part to have a single clickable button called “Start” which changes to “Stop” after clicked. I also want an indeterminent spinner running to show it is working.

Thanks for any help.

Ryan

Model: Macbook Pro
AppleScript: XCode 3
Browser: Safari 533.17.8
Operating System: Mac OS X (10.6)

Very good tutorial:
[u]http://macscripter.net/viewtopic.php?id=25631[/u]

Also, don’t use a repeat block and a delay for constant checks, use an idle handler.

Hope it helps,
ief2

Definitely good links. I can’t find any sample code for Cocoa in those links though. I’m trying to move away from Applescript Studio and do everything in Cocoa/Applescript. I haven’t taken any classes on this and have only started reading the latest Xcode book, which gives me ObjC examples instead.

I guess I’m having trouble figuring out how to place my code into the handler sections and associate it with IB.

So, here is where I am at. It is coming along nicely. The problem I am at now is I have to click on the “Start” button to get it to run each time. I want the app to continue to run until I click on “Stop”. Anyone have a coding suggestion?

script Power_DetectorAppDelegate
	property parent : class "NSObject"
	property startButton : missing value
	property endButton : missing value
	
	on clickStartButton_(sender)
		set the title of startButton to "Running"
		
		set PowerSource to (do shell script "pmset -g ps")
		
		if PowerSource does not contain "AC Power" then
			
			set recipientRyanEmail to "myanme@mac.com"
			set recipientRyanSMS to "mynumber@txt.att.net"
			set recipientRyanName to "Ryan R. Kubasiak"
			set theSubject to "POWER ALERT!"
			set theContent to return & return & "Battery Power!"
			try
				tell application "Mail"
					--Create the message
					set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:false}
					--Set a recipient
					tell theMessage
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanEmail}
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanSMS}
						--Send the Message
						send
						
					end tell
				end tell
			end try

		end if
	end clickStartButton_
	
	on clickQuitButton_(sender)
		set the title of startButton to "Start"
	end clickQuitButton_
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened 
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

I cannot code in AppleScriptObjc myself, but I guess you’ll have to make an NSTimer and call the handler.

This is what I have made of it without Snow Leopard and any experience, so the could could be completely wrong!

script Power_DetectorAppDelegate
	property parent : class "NSObject"
	property startButton : missing value
	property endButton : missing value
	property isRunning : false
	
	on clickStartButton_(sender)
		set isRunning to true
		set the title of startButton to "Running..."
		set enabled of startButton to false
		
		current application's NSTimer's timerWithTimeInterval_target_selector_userInfo_repeats_(10, me, "checkAC:", null, true)
	end clickStartButton_
	
	on clickQuitButton_(sender)
		set isRunning to false
		set the title of startButton to "Stopping..."
	end clickQuitButton_
	
	on checkAC_(theTimer)
		-- Invalidate if not running
		if not isRunning then
			theTimer's invalidate()
			set enabled of startButton to true
			set title of startButton to "Start"
			return
		end if
		
		set the title of startButton to "Running"
		
		set PowerSource to (do shell script "pmset -g ps")
		
		if PowerSource does not contain "AC Power" then
			
			set recipientRyanEmail to "myanme@mac.com"
			set recipientRyanSMS to "mynumber@txt.att.net"
			set recipientRyanName to "Ryan R. Kubasiak"
			set theSubject to "POWER ALERT!"
			set theContent to return & return & "Battery Power!"
			try
				tell application "Mail"
					--Create the message
					set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:false}
					--Set a recipient
					tell theMessage
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanEmail}
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanSMS}
						--Send the Message
						send
						
					end tell
				end tell
			end try
		end if
	end checkAC_
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened 
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

Hope it works,
ief2

Here are some examples you might want to look at. The best way is to let the system inform you when the computer goes on battery through the notification system.

If you run into problems setting it up, I would suggest posting your question on StackOverflow. There are plenty of C programmers there that can help.

Good luck!

http://developer.apple.com/mac/library/documentation/Darwin/Reference/IOKit/IOPowerSources_h/index.html

http://iphonesdkdev.blogspot.com/2009/01/source-code-get-hardware-info-of-iphone.html

http://blog.coriolis.ch/2009/02/14/reading-the-battery-level-programmatically/

I was able to get a working app! I have 2 buttons, Start and Stop that alternate back and forth between states. They are Push ON/OFF buttons. The main part of the app simply calls itself again as long as the Start button is still depressed. Thank you all for your help. Here is the code in case it can help anyone, or in case someone wants to refine it.

script Power_DetectorAppDelegate
	property parent : class "NSObject"
	property startButton : missing value
	property stopButton : missing value
	
	on clickStartButton_(sender)
		set the title of startButton to "Running"
		set the title of stopButton to "Stop"
		my startButton's setState_(true)
		my stopButton's setState_(false)
		getPowerStatus_()
	end clickStartButton_
	
	on getPowerStatus_()
		
		set PowerSource to (do shell script "pmset -g ps")
		
		if PowerSource does not contain "AC Power" then
			
			set recipientRyanEmail to "myemail@mac.com"
			set recipientRyanSMS to "mynumber@txt.att.net"
			set recipientRyanName to "Ryan R. Kubasiak"
			set theSubject to "POWER ALERT!"
			set theContent to return & return & "Battery Power!"
			try
				tell application "Mail"
					--Create the message
					set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:false}
					--Set a recipient
					tell theMessage
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanEmail}
						make new to recipient with properties {name:recipientRyanName, address:recipientRyanSMS}
						--Send the Message
						send
						
					end tell
				end tell
			end try
		end if --PowerSource does not contain "AC Power"
		
		if (startButton's |state|()) then
			getPowerStatus_()
		end if
	end getPowerStatus_
	
	on clickStopButton_(sender)
		set the title of startButton to "Start"
		set the title of stopButton to "Stopped"
		my startButton's setState_(false)
		my stopButton's setState_(true)
	end clickStopButton_
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened 
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script