Cycling and me

I am becoming a bit of a cycling enthusiast. Rather surprising at age 48. It’s not my first encounter with cycling, but it seems to have become my most intimate. I think it is about time to get something on the record. It is just my most recent episode of cycling. There have been many others over years.

EyeTV RecordingDone script, my take.

It is now more or less six years since I began watching telly exclusively using eyeTV running on my mac. To this day I have not found a better PVR, and I have tried a few. It has its niggles and features, but I am largely satisfied with its functionality. With ever larger screens available, it allows me to browse and watch telly at the same time. In fact it allows me to do whatever I am doing whilst watching telly in a small window. Sometimes I just use it the way I would a telly, with remote control and all. My current set up runs on a 2011 mac mini, using two Elgato DTT tuners. This allows me to record two programs simultaneously, or watch one and record on the other. I tend to record everything I want to watch. This way, I can pretty much avoid advertising, by never watching real-time (although limits the possibility of joining the twitter debate).

Prior to eyeTV 3, the downside was always having to leave the machine running, so as not to miss recording. The advent of eyeTV brought triggered scripts, whereby a script could be initiated on completion of a recording. Various RecordingDone scripts became available for download. I duly installed one of these, which would trigger after any program was recorded and if no other recording was in progress, it would sleep or close down the machine. It was now possible to save a bit of electricity usage, and remain confident that I wouldn’t miss any recordings.

 The following is a common example:


on RecordingDone(recordingID)
set isCurrentlyRecording to check_eyetv_is_recording()
if isCurrentlyRecording is false then
with timeout of 300 seconds
tell me to activate
display dialog "Warning: EyeTV has now finished recording and the system will automatically shut down in 5 minutes unless you click Stop!" with icon 2 buttons {"Stop!"} giving up after 300 default button "Stop!"
set theresults to the result
if gave up of theresults is true then
tell application "System Events" to sleep
end if
end timeout
else
quit
end if
end RecordingDone

to check_eyetv_is_recording()
delay 30
tell application "EyeTV"
if is_recording then
return true
else
return false
end if
end tell
end check_eyetv_is_recording

After a short while, I noticed a number of issues with this script. Often if I was browsing, whilst a recording came to an end, the dialog box may end up in the back ground and un noticed, so that the machine would just shut down whilst I continued to browse. Sometimes if two programs were recording, and ended simultaneously, one instance of the script would be un noticed so the machine would shut down. The only solution was to just get on and learn a bit of AppleScript and fix all the problems. So here is my solution, and also my first AppleScript. Try it if you wish.

So, what have you done with a 400 line script that couldn’t be done in 26? I hear you all ask.

Essentially I wanted to achieve the following:

  • Only allow one instance of the script to run at any one time
  • Log everything the script was up to
  • Avoid a shutdown failure if Firefox was taking too long to quit (which it often does if you use Xmarks)
  • Prevent the script from changing (or offering to change) the machine state if I was busy doing other things, such as
  • Browsing
  • Watchning EyeTV in full screen mode
  • Watching Quicktime movie
  • Listening to itunes
  • Watching a DVD

So, you may think it is cumbersome, but it works for me. The code may not be the best AppleScript you ever saw, and there may be better ways of doing things, but It is my first go at AppleScript.

For those who have never used a RecordingDone script before, all you have to do, is copy the below code, and paste it into a new text file (use text editor if you like). Save the file with the name RecordingDone.scpt in nameofyourharddrive/Library/Application Support/EyeTV/Scripts/TriggeredScripts. (Create this folder if it doesn’t already exist).

Job done.

--originally written by Brendan Ratcliffe 2011 myredroom.wordpress.com
global LogMsg
global posixLogFileName, fullLogFileName, fullFileName, posixFileName
global recordingNow, idletime, otherInstance
global currentRecordingID, thisRecordingTitle, referenceNumber
global itunesRunning, quicktimeRunning, DVDrunning, firefoxrunning
global itunesPlaying, quicktimePlaying, DVDplaying
global timeNow, nowPlus15Mins, nowPlus60Mins, soonestrecordingStart, soonestrecordingtitle

on RecordingDone(recordingID)
	set currentRecordingID to recordingID --save for later

	my initLogFile() --set up log file

	set errNum to 0

	set itemno to 1
	tell application "EyeTV"
		repeat with recid in unique ID of every recording
			if recid as text is equal to recordingID as text then
				set mytitle to title of item itemno of every recording
				my writetolog("RecordingDone script has been invoked, having completed recording (" & mytitle & ").")
			end if
			set itemno to itemno + 1
		end repeat
	end tell

	set anotherInstance to my check_for_another_instance()
	if anotherInstance then
		return
	end if

	set idletime to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'")
	my writetolog("The system has been idle for: " & idletime & " seconds.")

	try
		set realidletime to idletime as real
	on error
		my writetolog("error occurred in line: \"" & "set realidletime to idletime as real" & "\"")
		my deleteSwitchFile()
		return
	end try

	try
		set intidletime to round realidletime as integer

	on error
		my writetolog("error occurred in line: \"" & "set intidletime to round realidletime as integer" & "\"")
		my deleteSwitchFile()
		return
	end try

	tell application "EyeTV"

		if is_recording = true then
			my writetolog("eyeTV is currently recording another program. Therefore the machine state will not be altered.")
			my deleteSwitchFile()
			return
		end if
		--if playing is true and full screen is true then
		if full screen is true then --altered to handle bug in 3.5.4
			my writetolog("eyeTV is currently playing in full screen mode. Therefore the machine state will not be altered.")
			my deleteSwitchFile()
			return
		end if
		if playing is true and full screen is false then
			my writetolog("eyeTV is currently playing in a window.")
			if intidletime < 120 then
				my writetolog("eyeTV is currently playing in a window, but there has been user activity in the last 2 minutes. Therefore the machine state will not be altered.")
				my deleteSwitchFile()
				return
			end if
		end if
		if playing is false then
			my writetolog("eyeTV is not currently playing at all.")
			if intidletime < 120 then
				my writetolog("eyeTV is not currently playing, but there has been user activity in the last 2 minutes. Therefore the machine state will not be altered.")
				my deleteSwitchFile()
				return
			end if
		end if
		set timeNow to current date
		set nowPlus15Mins to (current date) + 15 * minutes
		set nowPlus60Mins to (current date) + 60 * minutes
		set soonestrecordingStart to (current date) + 1 * days
		my writetolog("Now searching for future recordings between now and " & soonestrecordingStart & ".")
		set itemno to 1
		repeat with thisRecordingStart in start time of every program
			if thisRecordingStart > timeNow and thisRecordingStart < soonestrecordingStart then
				set soonestrecordingStart to thisRecordingStart
				set soonestrecordingtitle to title of item itemno of every program
			end if
			set itemno to itemno + 1
		end repeat
		if soonestrecordingStart ≥ nowPlus15Mins then
			my writetolog("The soonest future recording (" & soonestrecordingtitle & ") will begin at " & soonestrecordingStart & ".")
		else
			my writetolog("eyeTV is scheduled to start another recording within the next 15 minutes (" & soonestrecordingtitle & ").")
			my writetolog("Therefore the machine state will not be altered.")
			my deleteSwitchFile()
			return
		end if
	end tell
	--at this point there may be good reason to offer sleep,
	--so lets do some more tests to determine what is going on on this system
	--if the eyeTV is in full screen, but paused then lets offer sleep/shutdown
	--now we will work out whether the system has other media player running
	tell application "System Events"
		set itunesRunning to (name of processes) contains "iTunes"
		set quicktimeRunning to (name of processes) contains "Quicktime Player"
		set DVDrunning to (name of processes) contains "DVD Player"
		set firefoxrunning to (name of processes) contains "Firefox"
	end tell
	if itunesRunning is true then
		tell application "iTunes"
			if player state is playing then
				set itunesPlaying to true
				my writetolog("iTunes has been found to be running and playing. Therefore the machine state will not be altered.")
				my deleteSwitchFile()
				return
			else
				set itunesPlaying to false
				my writetolog("iTunes has been found to be running but not playing. ")
				ignoring application responses
					quit
				end ignoring
			end if
		end tell
	else
		set itunesPlaying to false
		my writetolog("iTunes has been found not to be running. ")
	end if
	if quicktimeRunning is true then
		tell application "QuickTime Player"
			if exists document 1 then
				my writetolog("Quicktime has been found to be running.")
				set quicktimePlaying to false
				repeat with thisWindowActive in playing of every document
					if thisWindowActive is true then
						set quicktimePlaying to true
						my writetolog("Quicktime has been found to be running and playing. Therefore the machine state will not be altered.")
						my deleteSwitchFile()
						return
					end if
				end repeat
			else
				set quicktimePlaying to false
				my writetolog("Quicktime has been found to be running but not playing. ")
				ignoring application responses
					quit
				end ignoring
			end if
		end tell
	else
		set quicktimePlaying to false
		my writetolog("Quicktime has been found not to be running. ")
	end if
	if DVDrunning is true then
		tell application "DVD Player"
			if dvd state is playing then
				set DVDplaying to true
				my writetolog("DVD Player has been found to be running and playing. Therefore the machine state will not be altered.")
				my deleteSwitchFile()
				return
			else
				set DVDplaying to false
				my writetolog("DVD Player has been found to be running but not playing. ")
				ignoring application responses
					quit
				end ignoring
			end if
		end tell
	else
		set DVDplaying to false
		my writetolog("DVD Player has been found not to be running. ")
	end if
	my writetolog("Completed checks for other active players.")
	if soonestrecordingStart > nowPlus15Mins and soonestrecordingStart < nowPlus60Mins then
		my writetolog("got into first idle check check")
		(beep 2) activate
		set thisResponse to display dialog "EyeTV has just finished recording. Another recording will begin within the next hour. Would you like the computer to go into sleep mode?" buttons {"Yes", "No"} default button "No" with icon note with title "EyeTV-Recorder" giving up after 30
		if button returned of thisResponse = "" then
			my deleteSwitchFile()
			my writetolog("System sent to sleep because no response to sleep dialog.")
			tell application "Finder"
				ignoring application responses
					sleep
				end ignoring
				return
			end tell
		end if
		if button returned of thisResponse = "Yes" then
			my deleteSwitchFile()
			my writetolog("System sent to sleep because user responded \"Yes\" to sleep dialog.")
			tell application "Finder"
				ignoring application responses
					sleep
				end ignoring
				return
			end tell
		end if
		if button returned of thisResponse = "No" then
			my deleteSwitchFile()
			my writetolog("System state unaltered because user responded \"No\" to sleep dialog.")
			return
		end if
	else if soonestrecordingStart > nowPlus60Mins then
		--my writetolog("got into second idle check.")
		beep 2
		activate
		set thisResponse to display dialog "EyeTV has just finished recording. There are no scheduled recordings in the next hour. Would you like the computer shut down?" buttons {"Yes", "Sleep", "No"} default button "No" with icon note with title "EyeTV-Recorder" giving up after 30
		if button returned of thisResponse = "Yes" then
			if firefoxrunning is true then
				my quitFirefox()
			end if
			my deleteSwitchFile()
			my writetolog("System shutdown because user responded \"Yes\" to shutdown dialog.")
			tell application "Finder"
				ignoring application responses
					shut down
				end ignoring
				return
			end tell
		end if
		if button returned of thisResponse = "" then
			if firefoxrunning is true then
				my quitFirefox()
			end if
			my deleteSwitchFile()
			my writetolog("System shut down because no response to shutdown dialog.")
			tell application "Finder"
				ignoring application responses
					shut down
				end ignoring
				return
			end tell
		end if
		if button returned of thisResponse = "Sleep" then
			my deleteSwitchFile()
			my writetolog("System sent to sleep because user responded \"Sleep\" to shutdown dialog.")
			tell application "Finder"
				ignoring application responses
					sleep
				end ignoring
				return
			end tell
		end if
		if button returned of thisResponse = "No" then
			my deleteSwitchFile()
			my writetolog("System state unaltered because user responded \"No\" to shutdown dialog.")
			return
		end if
	end if

	my writetolog("Reached end of recordingDone script without altering the machine state. We shouldn't really have got here. Yikes.")
	my deleteSwitchFile()
	--display dialog "we are at the end of the recording done script"
end RecordingDone
---------------------------------------------------------------------------------------------------------------------------------------
on initLogFile()
	set fullLogFileName to ((path to documents folder as text) & "eyeTV-recordingDoneLog.txt")
	set posixLogFileName to POSIX path of fullLogFileName

	--check for existence of log file, if not existing then create it.
	tell application "Finder"
		if not (exists file fullLogFileName) then
			do shell script "touch " & quoted form of posixLogFileName
			my writetolog("This is the log file for eyeTV's recodingDone triggered script.")
			my writetolog("This file may be deleted at any time, recordingDone will create a new log as required.")
		end if
	end tell

end initLogFile
---------------------------------------------------------------------------------------------------------------------------------------
-- testing code: this will not be called when triggered from EyeTV, but only when the script is run as a stand-alone script
on run
	tell application "EyeTV"
		set rec to unique ID of item 1 of every recording
		my RecordingDone(rec)
	end tell
end run
---------------------------------------------------------------------------------------------------------------------------------------
on writetolog(logLine)
	set logLine to (current date) & ": eyeTV recordingID: " & currentRecordingID & ": " & logLine
	set fullCommand to "echo \"" & logLine & "\" >> " & posixLogFileName
	do shell script fullCommand
end writetolog
---------------------------------------------------------------------------------------------------------------------------------------
on quitFirefox()
	writetolog("Firefox has been found to be running. An attempt will be made to quit it before shutting down.")
	tell application "Firefox"
		quit
		delay 2 * minutes

	end tell
	set firefoxrunning to false

	tell application "System Events"
		set firefoxrunning to (name of processes) contains "Firefox"
	end tell
	if firefoxrunning is true then
		my writetolog("After waiting 2 minutes, firefox is still running, so this script will wait a further 2 minutes.")
		tell application "Firefox"
			ignoring application responses
				quit
			end ignoring
		end tell
		delay 2 * minutes
	else
		my writetolog("Firefox has successfully quit.")
		return
	end if

	set firefoxrunning to false

	tell application "System Events"
		set firefoxrunning to (name of processes) contains "Firefox"
	end tell
	if firefoxrunning is true then
		my writetolog("After waiting a further 2 minutes, firefox is still running, so this script will now force it to close.")
		do shell script "killall firefox"
		--delay 5 * minutes
	end if
end quitFirefox
---------------------------------------------------------------------------------------------------------
to check_for_another_instance()
	--lets put back the random duration wait again
	my writetolog("Now checking for another running instance of this script.")
	set otherInstance to false
	set fullFileName to ((path to documents folder as text) & "eyetvswitch.txt")

	set posixFileName to POSIX path of fullFileName

	set otherInstance to false

	--display dialog fullFileName
	--do shell script "rm -f " & quoted form of posixFileName
	tell application "Finder"
		if exists file fullFileName then
			my writetolog("Switch file has been found to exist.")
			try
				set referenceNumber to open for access fullFileName with write permission
			on error errText number errNum
				if (errNum is not equal to 0) then
					my writetolog("An error has occurred whilst trying to open switch for access(1): " & errNum & return & errText)
					set otherInstance to true
				end if
			end try
		else
			my writetolog("Switch file has been found not to exist. it will be created and locked.")
			try
				set referenceNumber to open for access fullFileName with write permission
			on error errText number errNum
				if (errNum is not equal to 0) then
					my writetolog("An error has  whilst trying to open switch for access(2): " & errNum & return & errText)
					set otherInstance to true
				end if
			end try

		end if
		if otherInstance = true then
			my writetolog("Another instance of this script is running, so this instance will exit without any further action.")
			return true
		else
			my writetolog("No other instance of this script is running, so it will continue and prevent others from running simultaneously.")
			return false
		end if
		return otherInstance
	end tell
end check_for_another_instance
---------------------------------------------------------------------------------------------------------------------------------------
on deleteSwitchFile()
	set errNum to 0
	if otherInstance = false then
		try
			close access referenceNumber
		on error errText number errNum
			if (errNum is not equal to 0) then
				do shell script "rm -f " & quoted form of posixFileName
				my writetolog("An error has occurred whilst closing switch file: " & errNum & return & errText)
			end if
		end try
		if errNum = 0 then
			my writetolog("Switch file successfully closed.")
		end if
		do shell script "rm -f " & quoted form of posixFileName
	end if
end deleteSwitchFile
---------------------------------------------------------------------------------------------------------------------------------------

The clock is ticking, all over again….

As I begin to write, 11 days, 15 hours, 40 minutes and 13 seconds is all that remains until the beginning of the first race weekend of the 2011 Formula 1 season.  I’ve been observing F1 for most of my life, but 1989 was the year when my interest (and understanding) increased to the sort of level it still is now. It also marked the start of the post turbo era and the return to normally aspirated engines. It might also have marked the start of an era in F1 when a Sunday afternoon procession of increasingly expensive motors began. A procession lacking many of the attributes you’d look for in a race – not least that holy grail of overtaking.

For me, I feel much the same as I have at this point in the last 21 seasons: optimistic. Those who know me would rarely describe as an optimistic person. I have always been optimistic that the coming season would provide: more overtaking, no team absolutely dominating, more than two potential winning drivers, more than one potential championship winning team. In these regards, I have usually been disappointed. That is not to say that I have been more generally disappointed. I haven’t – there have been some great spectacles and extraordinary battles, just all too often with only two protagonists (Senna/Prost, Schumacher/Hill,  Alonso/Schumacher, Schumacher/Hakinnen….). Every season, the technical battle and political strife provide a great deal of interest, without fail.

Without the degree of overtaking I would like, the next best thing to hope for is a season, where you cannot predict at the beginning who will triumph at the end; a season where there may be more than two different race winners. In all my time, it was 2003 that failed to disappoint. That is, of course until 2007.

What happened in 2007? (I hear you all say). The race, to the title that is, did not disappoint. It hasn’t disappointed since. There have been some processional races, but the last four seasons have provided interest right up to the wire – a bookie’s nightmare. The debate about what changed could rage and rage; the F1 rules are a work in progress and many factors change each year. The impact that any change will have on the racing is never easy to predict, and often is only understood with the help of much hindsight.

All I can offer is my own view. F1 has always had great drivers. In F1, just being a great driver is not enough. You need to be a great driver in the greatest  car of the season (or as Schumacher proved, an exceptional driver in a good car). F1 has shown me that being a supreme driver in another formula is no guarantee of F1 greatness; similarly drivers with no previous conspicuous greatness find their place in F1. For the last four years we have had a large number of great drivers at one time. How have we ended up with so many great drivers at once? I think it is because of the previous rules which allowed for more testing and the use of the third driver at race weekends (for the less successful teams) that has delivered so many greats at once. It was in this try before you buy era (now sadly ended) that the likes of Kubica, Vettel and Hamilton, found their way into the money seats. 15 years before they may not have had the chance to be seen. But it isn’t just a surplus of good drivers that has made the difference.

As ever in F1 it is not just about the driver. In the post turbo era, all too often there has been a predominant car and one which may be able to clip at its heels given the right circumstances. This seems to have changed since 2007 and we now have a number of cars which could win any given race. There could be a number of reasons for this: the standard electronics package; the ban on engine development; season limits on the number of engines used; a clearly defined limit to testing; the apparent ability of teams to develop cars within a season.  Often rule changes have little impact on the track but instead an impact on the car or how the team develops it.

All of this stands for the current season. But this year, I am slightly more optimistic than usual that we will see something other than a procession. For a start, we are going to have a different tyre supplier, providing tyres  designed to degrade more rapidly than last year’s. We shall therefore return to the strategic decision making that went with refueling. We shall also see the return of KERS . We have seen KERS before, but this time it might be fitted to more of the field and may be more reliable. This time around it is combined with a moveable rear wing, which can be deployed, by the driver, at parts of the track, as determined by the stewards. Even the drivers seem unable to predict whether it will indeed result in more overtaking or not – I couldn’t possibly say, but I’m sure it will provide much interest, both on and off the pitch.

It seems to me, that in this limited testing world that the teams now find themselves, risks have to be taken with the design. It can already be seen from the pre-season testing that many teams have come up with radical ideas: McLaren with its interesting sidepods, Red Bull and Renault with new (and different) exhaust systems; And that is just to mention a couple – even the lesser teams are will be trying radical things. Just by looking at the cars, I can’t help feeling, that thus far there is no certain or prescribed way of building the fastest car for this season. We shall have to wait and see who has got it right. Few would doubt that the Red Bull and Ferrari will be fast cars, and that the McLaren and Mercedes will become fast cars. But this year there might just be one or two surprises from the mid field, or even the rear.

Bring it on, just 11 days, 12 hours, 49 minutes and 47 seconds to go.

Create a free website or blog at WordPress.com.

Up ↑