{"id":24,"date":"2013-06-05T17:03:59","date_gmt":"2013-06-05T07:03:59","guid":{"rendered":"https:\/\/www.icemoonprison.com\/blog\/?p=24"},"modified":"2013-06-17T16:53:06","modified_gmt":"2013-06-17T06:53:06","slug":"the-wednesday-problem-checking-how-many-tuners-eyetv-needs-for-scheduled-recordings","status":"publish","type":"post","link":"https:\/\/www.icemoonprison.com\/blog\/archives\/24","title":{"rendered":"The Wednesday Problem: Checking how many tuners EyeTV needs for scheduled recordings"},"content":{"rendered":"<p>Here at Ice Moon Prison, inmates receive the Australian digital free-to-air broadcast, on the assumption that it is the least consumer-friendly television ecosystem in existence. Shows routinely run late, requiring those using PVR software to add at least 20 minutes to each scheduled recording Just In Case. Networks also collude and ensure that all the shows you actually want to watch are scheduled at the same time on different channels. We call this the Wednesday Problem.<\/p>\n<p>Ice Moon Prison uses EyeTV and HDHomeRuns for a total of four tuners. This is usually sufficient except for the busiest Wednesdays. Rather than manually check the schedule and count whether five or more tuners are needed at any given time, we have an AppleScript &#8230; er, script, which gets this information straight from EyeTV and reports how many tuners are needed for its upcoming scheduled recordings.<\/p>\n<p><!--more--><\/p>\n<pre>local now, schedule_list, eyetv_programs, eyetv_recordings, concurrent_limit\r\nset now to current date\r\n-- How many tuners are available?\r\nset concurrent_limit to 4\r\nset schedule_list to {}\r\ntell application \"EyeTV\"\r\n    set eyetv_programs to programs\r\n    set eyetv_recordings to recordings\r\n\r\n    repeat with schedule in eyetv_programs\r\n        local sched_start_time, sched_end_time, sched_channel, matching_recording\r\n        set sched_start_time to (start time of schedule) - prepad time * 60\r\n        set sched_end_time to sched_start_time + (duration of schedule) + prepad time * 60 + postpad time * 60\r\n        set sched_channel to channel number of schedule\r\n        set matching_recording to 0\r\n        repeat with rec in eyetv_recordings\r\n            local recording_start_time, recording_end_time, recording_channel\r\n            set recording_start_time to actual start of rec\r\n            set recording_end_time to recording_start_time + (actual duration of rec)\r\n            set recording_channel to channel number of rec\r\n            if (recording_channel = sched_channel and recording_start_time ? sched_start_time and recording_end_time ? sched_end_time) then\r\n                        set matching_recording to unique ID of rec\r\n                        exit repeat\r\n            end if\r\n        end repeat\r\n        if (matching_recording = 0) then\r\n            copy schedule to end of schedule_list\r\n        end if\r\n    end repeat\r\nend tell\r\n\r\nlocal tuners_needed, overlap_list\r\nset tuners_needed to 0\r\nset overlap_list to {}\r\n\r\nrepeat with candidate in schedule_list\r\n    tell application \"EyeTV\"\r\n        local candidate_start_time -- , candidate_end_time\r\n        set candidate_start_time to (start time of candidate) - prepad time * 60\r\n        local overlap\r\n        set overlap to 0\r\n        repeat with contestant in schedule_list\r\n            local contestant_start_time, contestant_end_time\r\n            set contestant_start_time to (start time of contestant) - prepad time * 60\r\n            set contestant_end_time to contestant_start_time + (duration of contestant) + prepad time * 60 + postpad time * 60\r\n            if (candidate_start_time ? contestant_start_time and candidate_start_time ? contestant_end_time) then\r\n                set overlap to overlap + 1\r\n            end if\r\n        end repeat\r\n        if (overlap &gt; tuners_needed) then set tuners_needed to overlap\r\n        if (overlap &gt; concurrent_limit) then\r\n            log name of candidate &amp; \" \" &amp; overlap\r\n        end if\r\n        if (overlap &gt; concurrent_limit and overlap_list does not contain candidate_start_time) then\r\n            copy candidate_start_time to end of overlap_list\r\n        end if\r\n    end tell\r\nend repeat\r\n\r\nlocal output\r\n\r\nif (length of overlap_list &gt; 0) then\r\n    set output to \"2\" &amp; return &amp; tuners_needed &amp; \" tuners needed\"\r\n    repeat with start_time in overlap_list\r\n        set output to output &amp; return &amp; (start_time as string)\r\n    end repeat\r\nelse\r\n    set output to \"0\" &amp; return &amp; tuners_needed &amp; \" tuners needed\"\r\n    return output\r\nend if<\/pre>\n<p>Run this script like so, using tr to convert AppleScript&#8217;s carriage returns to line feeds:<\/p>\n<pre>$ osascript eyetv-overlap-check.applescript | tr '\\015' '\\012'\r\n0\r\n4 tuners needed<\/pre>\n<p>The first line is 0 if there are enough tuners, 2 otherwise, designed to be fed into a <a title=\"Nagios home page\" href=\"http:\/\/www.nagios.org\/\">Nagios<\/a> <a title=\"Documentation: plugin api\" href=\"http:\/\/nagios.sourceforge.net\/docs\/nagioscore\/3\/en\/pluginapi.html\">check script<\/a> like this one:<\/p>\n<pre>#!\/bin\/sh\r\n\r\nprint_usage() {\r\necho \"check_osascript user applescript.scpt\"\r\n}\r\n\r\nif [ $# -lt 2 ]; then\r\nprint_usage;\r\nexit $STATE_OK\r\nfi\r\n\r\nscript=\"$1\"\r\n\r\nosascript_status=3\r\n\r\n# Run script, translating Mac OS Classic line ends into Unix ones.\r\nsudo -u \"$1\" osascript \"$2\" | tr '\\015' '\\012' &gt; \/tmp\/check-osascript.$$\r\n\r\nif [ $? -ne 0 ]; then\r\nexit 3\r\nfi\r\n\r\nexec 0&lt;\/tmp\/check-osascript.$$\r\n\r\n# First line is exit status.\r\nread osascript_status\r\n\r\n# Remaining lines are echoed as-is.\r\nwhile read; do\r\necho $REPLY\r\ndone\r\n\r\nrm -f \/tmp\/check-osascript.$$\r\n\r\nexit $osascript_status<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Here at Ice Moon Prison, inmates receive the Australian digital free-to-air broadcast, on the assumption that it is the least consumer-friendly television ecosystem in existence. Shows routinely run late, requiring those using PVR software to add at least 20 minutes to each scheduled recording Just In Case. Networks also collude and ensure that all the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[4,5],"tags":[6],"class_list":["post-24","post","type-post","status-publish","format-standard","hentry","category-eyetv","category-nagios","tag-applescript"],"_links":{"self":[{"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/posts\/24","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/comments?post=24"}],"version-history":[{"count":9,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/posts\/24\/revisions"}],"predecessor-version":[{"id":126,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/posts\/24\/revisions\/126"}],"wp:attachment":[{"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/media?parent=24"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/categories?post=24"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.icemoonprison.com\/blog\/wp-json\/wp\/v2\/tags?post=24"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}