--v1.1
property my_password : ""
property progress_counter : 0
property big_sur : false
property script_run_thru : false
property samples : 15
property sample_ms : 100
property yes_timeout : 0
on run
   
   
    -- get the sudo password, should not ask for it when running yes
    do_shell_script_sudo("echo 1")
   
   
    set script_run_thru to false
    set progress_counter to 0
   
    progress(5, "probing CPU Type")
    try
        set StrCPU to (do shell script ("sysctl -a | grep machdep.cpu.brand_string"))
        set AppleScript's text item delimiters to ": "
        set StrCPU to last text item of StrCPU
        set AppleScript's text item delimiters to ""
    on error
        set StrCPU to ""
    end try
   
   
    -- big sur (or later) ?  (has a bug in do shell script with password, need a workaround)
   
    try
        set boot_rom_version to last word of (do shell script "system_profiler SPHardwareDataType | grep -i \"Boot Rom Version\"")
        if (length of boot_rom_version is 7) and (character 1 of boot_rom_version is "1") then -- older Systems like Mavericks truncates the sn
            set boot_rom_version to boot_rom_version & ".0"
        end if
        set big_sur to false
    on error --Big Sur
        set boot_rom_version to last word of (do shell script "system_profiler SPHardwareDataType | grep -i \"System Firmware Version\"")
        set big_sur to true
    end try
   
   
   
    set yes_timeout to (samples * (sample_ms / 1000) as integer) + 10 -- extra time for proceeding the script, thats just a failback of the script is shut down
   
   
   
   
   
    progress(5, "running yes on 1 core")
   
    do_shell_script_in_background("yes")
    do_shell_script_in_background("echo 'sleep " & (yes_timeout as string) & ";killall yes' | sh")
   
   
   
    progress(5, "powermetrics start")
   
    -- powermetrics needs to start in background if not the readings are not consistent, differ from running in Script Editor
   
    do_shell_script_sudo_in_background("powermetrics -n" & samples & space & "-i" & sample_ms & " --output-file /tmp/powermetrics.txt")
   
   
    set the_timeout to (samples * (sample_ms / 1000) as integer) + 2 -- extra time for proceeding the script
   
   
    delay the_timeout -- powermetrics needs some time to finish the output file !
   
    do_shell_script_sudo("cat /tmp/powermetrics.txt | grep 'System Average frequency as fraction of nominal' >/tmp/powermetrics2.txt")
    do_shell_script_sudo("rm /tmp/powermetrics.txt")
    do_shell_script_sudo("mv /tmp/powermetrics2.txt /tmp/powermetrics.txt")
   
   
    progress(5, "powermetrics done")
   
    try
        do shell script "killall yes"
    end try
   
    progress(5, "killall yes")
   
    set readout to do shell script "cat /tmp/powermetrics.txt"
   
    set cpu_percentages to do shell script "cat /tmp/powermetrics.txt | awk '{print $(NF-2)}' | sed 's/.$//'"
   
   
    set readout to paragraph 1 of readout
   
    set percentage to (word -3 of readout) as real
    set frequency to (word -2 of readout) as real
    set nominal_cpu_frequency to frequency / percentage * 100 as integer
   
    -- every word of readout: {"System", "Average", "frequency", "as", "fraction", "of", "nominal", "76.93", "1077.01", "Mhz"}
   
    set samples to count every paragraph in cpu_percentages
    set average to listAvg(every paragraph of cpu_percentages)
    set sampled_frequency to (nominal_cpu_frequency * average) / 100 as integer
   
   
    activate me
   
   
   
   
    display dialog StrCPU & return & "actual CPU Frequency: " & (sampled_frequency as string) & " Mhz" & return & ¬
        "nominal CPU Frequency: " & (nominal_cpu_frequency as string) & " Mhz" & return & ¬
        "samples: " & (samples as string) with title "Macschrauber's turbo CPU frequency teller" buttons {"OK"} default button "OK"
   
   
    try
        do_shell_script_sudo("rm /tmp/powermetrics.txt")
    end try
   
   
    set script_run_thru to true
   
   
   
end run
on quit
    if (not script_run_thru) then
        activate me
        progress(5, "stop, killall yes just in case")
        try
            do shell script "killall yes"
        end try
    end if
   
    contine quit
end quit
on listAvg(theList)
    set the_list to theList
    set a to 0
    repeat with this_item in the_list
        set a to a + (this_item as real)
    end repeat
    set avg to (a / (count the_list)) as real
    return avg
end listAvg
on do_shell_script_sudo(the_text)
    if my_password is not "" then
        if big_sur then
            try -- if the password is wrong it runs into an error
                return do shell script "echo " & my_password & " | sudo -S " & the_text
            on error number errorNumber
                --display dialog (errorNumber as text) & return & the_text
                return do shell script the_text with administrator privileges
                -- and ask for the correct password
            end try
           
        else -- does not run into an error
            try
                return do shell script the_text password my_password with administrator privileges
            on error
                return do shell script the_text with administrator privileges
            end try
        end if
       
    else -- no password given
        return do shell script the_text with administrator privileges
    end if
   
end do_shell_script_sudo
on do_shell_script_in_background(the_command)
    do shell script (the_command & " > /dev/null 2>&1 &")
end do_shell_script_in_background
on do_shell_script_sudo_in_background(the_command)
    do shell script (the_command & " > /dev/null 2>&1 &") password my_password with administrator privileges
end do_shell_script_sudo_in_background
on progress(progress_total_steps, progress_description)
    try
        log progress_description
        set progress total steps to progress_total_steps
        set progress_counter to progress_counter + 1
        set progress completed steps to progress_counter
        set progress description to progress_description
        delay 1
    end try
end progress