Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
ok, i want to make a mac program that keeps track of your computer's uptime, keep a record uptime, and maybe average uptime and more statistics if possible.

i have taken a few programming courses, but only matlab, visual basic, and C#, so they don't really help me with this one.

i have gone through a few mac tutorials, but they weren't like the program i want.

i know there is a widget called "show-off" that basically does this, but i have computers on panther, and i just want to make my own program

if anyone could help me get started, i'd really appreciate it. i don't really know how to start this

thanks in advance
 

MongoTheGeek

macrumors 68040
ok, i want to make a mac program that keeps track of your computer's uptime, keep a record uptime, and maybe average uptime and more statistics if possible.

The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes

A simple obj-C application will use less CPU resource than applescript, but assuming you have a modern Mac (fast G4/G5/Intel) you'll be OK, from experience an applescript application (on an iMac G5) uses about 0.3% CPU while sleeping.
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong

thanks for the link. have you used this book before yourself?

The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes

thanks. so if i copy and paste this into an AppleScriptStudio application, it will work? or do i need to change it some?

A simple obj-C application will use less CPU resource than applescript, but assuming you have a modern Mac (fast G4/G5/Intel) you'll be OK, from experience an applescript application (on an iMac G5) uses about 0.3% CPU while sleeping.

well i would be running this on a G4 mac mini.....so any help in speed would be nice
 

MongoTheGeek

macrumors 68040
thanks. so if i copy and paste this into an AppleScriptStudio application, it will work? or do i need to change it some?

The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.

ok thanks. i'll see what i can come up with
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.

well i got it working. but it doesn't do anything yet. what do you think would be the best way to display the uptime on the screen?
 

MongoTheGeek

macrumors 68040
well i'm gonna be honest here, i've tried to do this, but i'm not really sure how to go about it. could you help me out with it?


thanks in advance

I was away at WWDC and not watching the forums.

Did you end up with the Cocoa solution or the AS solution.

For AS
set contents of text field "Foo" to timewords

The text field has to be named "Foo" in Applescript in Interface Builder for this to work.



For Cocoa
[myTextField setStringValue:timeWords];

The text field has to be connected to an IBOutlet on the class you are working on.
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
I was away at WWDC and not watching the forums.

Did you end up with the Cocoa solution or the AS solution.

For AS
set contents of text field "Foo" to timewords

The text field has to be named "Foo" in Applescript in Interface Builder for this to work.



For Cocoa
[myTextField setStringValue:timeWords];

The text field has to be connected to an IBOutlet on the class you are working on.

thanks. i'm trying the AS version.

i did what you said, but nothing is showing up in the text box. i set it to uneditable. is that a problem? i don't want to be able to type in the box
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
thanks. i'm trying the AS version.

i did what you said, but nothing is showing up in the text box. i set it to uneditable. is that a problem? i don't want to be able to type in the box

Uneditable is fine, you have to make sure the box is being pointed too correctly from the code.
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
well i need some help here. first, i tried to use the code that was given to me in this thread in applescript studio, but i couldn't figure out how to put it in a textbox.

the last 2 nights i've been working with a few other members on a cocoa application that does the same thing, and none of us can figure out how to get the uptime. we tried this, but it doesn't work right:

Code:
double newVar = currentTimeAsDuration;
	
	NSString *Astring = [NSString stringWithFormat:@"%f", newVar]; 	
	
	double value = [Astring intValue]; 

	double inSeconds = value * .0001; //mili-sec
	double inMinutes = inSeconds / 60; //sec-min
	double inHours = inMinutes / 60; //min-hour
	
	NSString *string = [NSString stringWithFormat:@"%f", inHours];
	
	NSString *hoursExtract = [string substringToIndex:1];
	NSString *minutesExtract = [string substringWithRange:NSMakeRange(2,2)];
	NSString *secondsExtract = [string substringWithRange:NSMakeRange(4,2)];
	
	NSString *finalString = [NSString stringWithFormat:@"%@h %@m %@s", hoursExtract, minutesExtract, secondsExtract];
	
	
	[textField setStringValue:finalString]

so if anyone can help, that would be great.

thanks
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
well me and rev316 got it to display your uptime correctly.

now the next step is to keep a record of your best (longest) uptime.

can anyone help us out with that? storing data is a little over my head right now

thanks
 

Nutter

macrumors 6502
Mar 31, 2005
432
0
London, England
Could you post your whole Xcode project here? I can't really see from the snippet above what is going on...

Also, do you only want to store the longest uptime, or do you want more detailed stats?
 

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
Could you post your whole Xcode project here? I can't really see from the snippet above what is going on...

Also, do you only want to store the longest uptime, or do you want more detailed stats?

here is the updated code:

Code:
#import "uptimeApp.h"

@implementation uptimeApp


- (IBAction)createTime:(id)sender
{
	AbsoluteTime currTime; 
	currTime = UpTime();
	
    float currentUptime = (float)AbsoluteToDuration(currTime);
	if (0.0f > currentUptime) // negative means microseconds
	currentUptime /= -1000000.0f;
    else // positive means milliseconds
	currentUptime /= 1000.0f;

    int days = 0;
	
    float currentUptimeinMinutes = currentUptime / 60;
    
   	int hours = (int)currentUptimeinMinutes / 60; //get hours	
  	int diffHinMin = hours * 60; //find the minutes of the hours	
  	int minutes = currentUptimeinMinutes - diffHinMin; //difference to get minutes
  	 	
    if (minutes > 59)
  	{
        hours += 1;
        minutes = 0;
    }
  	
  	if (hours > 23)
  	{
        days = hours / 24;
        hours = hours % 24;
    }
  	
    NSString *string = [NSString stringWithFormat:@"%dd %dh %dm", days, hours, minutes];
	[textField setStringValue:string];  // display it in our outlet
}    
@end

thanks. well, eventually we would like to hold more stats if possible, like your last 10 uptimes or something.
 

Nutter

macrumors 6502
Mar 31, 2005
432
0
London, England
Here's my solution. I've changed the name of your class to AppController, because it makes more sense (and starts with a capital letter!).

AppController.h:

Code:
#import <Cocoa/Cocoa.h>


@interface AppController : NSObject
{
	IBOutlet NSTextField *textField;
}

- (IBAction)createTime:(id)sender;

- (NSNumber *)longestRecordedUpTime;
- (NSArray *)lastTenRecordedUpTimes;
@end

AppController.m:
Code:
#import "AppController.h"

NSString *MBLongestRecordedUpTime = @"MBLongestRecordedUpTime";
NSString *MBLastTenRecordedUpTimes = @"MBLastTenRecordedUpTimes";


@interface NSNumber (MBUpTimeAdditions)

+ (id)currentUpTime;
- (NSString *)formattedUpTimeString;
@end


@implementation AppController

- (IBAction)createTime:(id)sender;
{
	NSNumber *currentUpTime = [NSNumber currentUpTime];
	[textField setStringValue:[currentUpTime formattedUpTimeString]];
	
	if ([[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime] == nil || [currentUpTime compare:[[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime]] == NSOrderedDescending)
		[[NSUserDefaults standardUserDefaults] setObject:currentUpTime forKey:MBLongestRecordedUpTime];
		
	NSMutableArray *lastTenUpTimes = [[[NSUserDefaults standardUserDefaults] objectForKey:MBLastTenRecordedUpTimes] mutableCopy];
	if (lastTenUpTimes == nil)
		lastTenUpTimes = [[NSMutableArray alloc] initWithCapacity:10];
	[lastTenUpTimes insertObject:currentUpTime atIndex:0];
	if ([lastTenUpTimes count] > 10)
		[lastTenUpTimes removeLastObject];
	[[NSUserDefaults standardUserDefaults] setObject:lastTenUpTimes forKey:MBLastTenRecordedUpTimes];
	[lastTenUpTimes release];
}

- (NSNumber *)longestRecordedUpTime;
{
	return [[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime];
}

- (NSArray *)lastTenRecordedUpTimes;
{
	return [[NSUserDefaults standardUserDefaults] objectForKey:MBLastTenRecordedUpTimes];
}

@end


@implementation NSNumber (MBUpTimeAdditions)

+ (id)currentUpTime;
{
	return [self numberWithUnsignedLongLong:UnsignedWideToUInt64(AbsoluteToNanoseconds(UpTime())) / 1000000000];	// UpTime in seconds
}

- (NSString *)formattedUpTimeString;
{
	unsigned days = [self unsignedLongLongValue] / (60 * 60 * 24);
	unsigned hours = ([self unsignedLongLongValue] / (60 * 60)) % 24;
	unsigned minutes = ([self unsignedLongLongValue] / 60) % 60;
	
	return [NSString stringWithFormat:@"%ud %uh %um", days, hours, minutes];
}

@end
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.