Skip to content

Commit

Permalink
Upload the entire script
Browse files Browse the repository at this point in the history
  • Loading branch information
Piero24 committed Oct 28, 2023
1 parent cfc261a commit 4907a04
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 5 deletions.
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,4 @@ iOSInjectionProject/

# Other files
.DS_Store
PlugNPlayMac.sh
PNPMacInstaller.sh
PNPMacParam.sh
com.launch.plug.and.play.mac.plist
personalParam.sh
58 changes: 58 additions & 0 deletions PNPMacInstaller.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

# Function to display an error message as a popup
display_error() {
osascript -e "display dialog \"$1\" buttons \"OK\" default button \"OK\" with title \"Error\""
}

# Make the directory for the PlugNPlayMac files
sudo mkdir /usr/local/bin/PlugNPlayMac
if [ $? -ne 0 ]; then
display_error "Error creating PlugNPlayMac directory"
exit 1
fi

# Move files to /usr/local/bin/PlugNPlayMac
sudo mv PlugNPlayMac.sh /usr/local/bin/PlugNPlayMac
if [ $? -ne 0 ]; then
display_error "Error moving PlugNPlayMac.sh"
exit 1
fi

sudo mv PNPMacParam.sh /usr/local/bin/PlugNPlayMac
if [ $? -ne 0 ]; then
display_error "Error moving PNPMacParam.sh"
exit 1
fi

# Copy the plist file to /Library/LaunchAgents
sudo cp com.launch.plug.and.play.mac.plist /Library/LaunchAgents
if [ $? -ne 0 ]; then
display_error "Error copying com.launch.plug.and.play.mac.plist"
exit 1
fi

# Move the plist file to /usr/local/bin/PlugNPlayMac
sudo mv com.launch.plug.and.play.mac.plist /usr/local/bin/PlugNPlayMac
if [ $? -ne 0 ]; then
display_error "Error moving com.launch.plug.and.play.mac.plist"
exit 1
fi

echo "All files moved/copied successfully."

chmod +x /usr/local/bin/PlugNPlayMac/PlugNPlayMac.sh

printf "\nLAST STEPS:\n\n"

printf "1) Digit on therminal /usr/local/bin/PlugNPlayMacPlugNPlayMac.sh ad enter your password
2) control + c to exit
3) Open System Settings > Privacy & Security > Full Disk Access
4) Click on the plus icon at the bottom of the list and digit your password
5) Press cmd + shift + G and digit /bin
6) Select bash and click open
7) Click again on the plus icon at the bottom of the list and digit your password
8) Press cmd + shift + G and digit /usr/local/bin/PlugNPlayMac
9) Select blcm and click open
10) Reboot your Mac
11) Open terminal and digit launchctl load /Library/LaunchAgents/com.launch.plug.and.play.mac.plist\n"
23 changes: 23 additions & 0 deletions PNPMacParam.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# List of Wi-Fi names
listWifiNames=("Wifi Name" "Other Wifi Name")
# List of Display names
listDisplayNames=("Display Name" "Other Display Name")
# List of Apps to open
listAppToOpen=("App Name" "Other App Name" "Other App Name")
# Max battery level when connected
batteryValue=77
# Delay in seconds (default 60 seconds)
seconds4Delay=60
# Username of the account to use for sudo operation
accountUser="MY USERNAME"

# security add-generic-password -s 'CLI Test' -a 'armin' -w 'password123'


getPW() {
# Take the password from apple Keychain for operate the sudo operation
#
local my_var
my_var=$(security find-generic-password -w -s "PlugNPlayMac" -a "$accountUser")
echo "$my_var"
}
236 changes: 236 additions & 0 deletions PlugNPlayMac.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#!/bin/bash

# Find it in the list without searching and then delete. It's just a dumb bug.
# https://apple.stackexchange.com/a/344380/460842

# bash -c "nohup caffeinate -u -i -d &"
# ps aux -o ppid | grep caffeinate
# launchctl load /Library/LaunchAgents/com.launch.mac.studio.setup.plist
# launchctl unload /Library/LaunchAgents/com.launch.mac.studio.setup.plist
#
# BEFORE STARTING THE SCRIPT WITH launchctl load YOU MAST GIV FULL DISK ACCESS TO /BIN/BASH AND BCLM

source /usr/local/bin/PlugNPlayMac/PNPMacParam.sh

myPassword=$(getPW)
# ID of the last active caffeinate process (0 at start of the script)
PMSETPID=0
# Flag for know if the script is active
isAlreadyOn=0
# mkdir ~/Mac\ Studio \Setup
parentPath=/usr/local/bin/PlugNPlayMac
# CPU Architecture (Intel: x86_64 --- Apple Silicon: arm64)
isAppleSilicon=false
architecture=$(uname -m)

if [[ "$architecture" == *"arm64"* ]]; then
isAppleSilicon=true

elif [[ "$architecture" == *"x86_64"* ]]; then
isAppleSilicon=false

else
date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: Problem during the detection of the CPU architecture"
exit 1

fi

while true; do

isDisplayFound=false;
isWifiFound=false;
isSleep=false

# Return the name of the different display connected to the mac
# If the built in display is connected but close it doesn't appear
commandDetectDisplay="ioreg -lw0 | grep 'IODisplayEDID' | sed '/[^<]*</s///' | xxd -p -r | strings -10"
currentDisplay=$(eval "$commandDetectDisplay")
# echo "$currentDisplay"

# Return the name of the wifi connected to the mac
commandDetectWifi="/Sy*/L*/Priv*/Apple8*/V*/C*/R*/airport -I | awk '/ SSID:/ {print $2}'"
currentWifi=$(eval "$commandDetectWifi")
# echo "$currentWifi"

# Return the curret battery percentage
# commandDetectBattery="pmset -g batt | grep -Eo \"\\d+%\" | cut -d% -f1"
# currentBattery=$(eval "$commandDetectBattery")
# echo "$currentBattery"

# Iterate through the list of display names
# Set isDisplayFound to true if there is a match on the display
for displayName in "${listDisplayNames[@]}"; do
if [[ "$currentDisplay" == *"$displayName"* ]]; then
isDisplayFound=true
break
fi
done

# Iterate through the list of wifi names
# Set isWifiFound to true if there is a match on the wifi
for wifiName in "${listWifiNames[@]}"; do
if [[ "$currentWifi" == *"$wifiName"* ]]; then
isWifiFound=true
break
fi
done

# If the script is not already active but the display is connected and the mac connected to the wifi
if [[ $isAlreadyOn -eq 0 && $isDisplayFound == true && $isWifiFound == true ]]; then

# Launch a nohup caffeinate for run caffeinate in background
# This prevent the mac to sleep
# "man caffeinate" for more information
nohup caffeinate -u -i -d &
# save the caffeinate process ID
PMSETPID=$!
# kill $PMSETPID

isAlreadyOn=1;

date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: Starting caffeinate with ID: $PMSETPID"

# Open each application in the list
for applicationName in "${listAppToOpen[@]}"; do
open -a "$applicationName"
date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: Starting the APP: $applicationName"
done

if $isAppleSilicon; then
# At this moment the battery doesn't set the new charge limit
# on Apple Silicon. This is because the BCLM script doesn't
# work on Apple Silicon.
echo "$date_string: Not done yet for Apple Silicon"
else
# More info on BCLM here: https://github.com/zackelia/bclm
# Overwrite battery value and set the new value for the battery limit
echo $myPassword | sudo -S chmod +x "$parentPath/bclm"
echo $myPassword | sudo -S "$parentPath/bclm" write "$batteryValue"
# Apply the persistence for the new battery limit
error_message=$(echo "$myPassword" | sudo -S "$parentPath/bclm" persist 2>&1)

date_string=$(date +"%d %b %Y - %H:%M")

if [ $? -eq 0 ]; then
echo ""
echo "$date_string: Persistence has bean activte"
fi

# Read the current battery value
result="$("$parentPath/bclm" read)"
echo "$date_string: Result of bclm read: $result"
fi

fi

# If the script is already active but the display isn't connected
if [[ $isAlreadyOn -eq 1 && $isDisplayFound == false ]]; then

isAlreadyOn=0;

# Kill all the caffeinate process
pkill caffeinate

date_string=$(date +"%d %b %Y - %H:%M")

# Check if any instances were killed
if [ $? -eq 0 ]; then
echo "$date_string: All caffeinate process killed successfully"
else
echo "$date_string: No caffeinate process found to kill"
fi

# Close each application in the list
for applicationName in "${listAppToOpen[@]}"; do
osascript -e "tell application \"$applicationName\" to quit"
date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: $applicationName closed correctly"
done

if $isAppleSilicon; then
echo "$date_string: Not done yet for Apple Silicon"
else

# Remove persistence on the battery for set the default value
error_message=$(echo $myPassword | sudo -S "$parentPath/bclm" unpersist 2>&1)
date_string=$(date +"%d %b %Y - %H:%M")

if [ $? -eq 0 ]; then
echo "$date_string: Persistence has bean disabled"
fi

# Write the original value
echo $myPassword | sudo -S "$parentPath/bclm" write 100
# Remove the plist file of BCLM for prevent problem with the default value
echo $myPassword | sudo -S rm /Library/LaunchDaemons/com.launch.plug.and.play.mac.bclm.plist
fi
fi

# This part untill the "sleep $seconds4Delay" is only for precaution. In case the mac
# After receiving the sleep command from the menu bar don't goes correctly in sleep mode.
# It will kill caffeinate in case of problem for help the mac to go in sleep mode correctly.

# Check if the display is in sleep mode
# If yes, kill the caffeinate process and set the sleep flag to true
if system_profiler SPDisplaysDataType | grep -q "Display Asleep: Yes"; then
isSleep=true
sleep 30
pkill caffeinate

date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: Persistence has bean disabled"

fi

# Costantly check if the display is in sleep mode.
while [ "$isSleep" == true ]; do
# When the status change from sleep to awake, start a new caffeinate process
if ! system_profiler SPDisplaysDataType | grep -q "Display Asleep: Yes"; then
isSleep=false
nohup caffeinate -u -i -d &
# save the caffeinate process ID
PMSETPID=$!

date_string=$(date +"%d %b %Y - %H:%M")
echo "$date_string: Persistence has bean disabled"

else
sleep 30

fi
done

sleep $seconds4Delay

# Get the creation date of a file
creation_date=$(GetFileInfo -d /private/tmp/plug.and.play.mac.log | cut -d ' ' -f 1)

# Get the current date
current_date=$(date +"%m/%d/%Y")

# Convert the dates to timestamps using the 'date' command
timestamp1=$(date -j -f "%m/%d/%Y" "$creation_date" "+%s" 2>/dev/null)
timestamp2=$(date -jf "%m/%d/%Y" "$current_date" "+%s")

date_string=$(date +"%d %b %Y - %H:%M")

if [ -n "$timestamp1" ] && [ -n "$timestamp2" ]; then
# Calculate the time difference in seconds
difference=$((timestamp2 - timestamp1))

# Calculate the number of days in the time difference
days_difference=$((difference / 86400)) # 86400 seconds in a day

if [ "$days_difference" -ge 10 ]; then
# Delete the log file
rm /private/tmp/plug.and.play.mac.log
echo "$date_string: Log file deleted"
fi
else
echo "$date_string:Date conversion error"
fi

done
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,17 @@

8. Reboot your Mac

9. Open terminal and digit `launchctl load /Library/LaunchAgents/com.launch.plug.and.play.mac.plist``
9. Open terminal and digit `launchctl load /Library/LaunchAgents/com.launch.plug.and.play.mac.plist`

Done! Now the script will run automatically when you connect your Mac to the monitor and will close when you disconnect it. Additionally, you can use the shortcut to enable/disable various functions from the Mac's menu bar.
👉 You can get the PlagNPlayMac shortcut from this <a href="https://www.icloud.com/shortcuts/f17d6b70db3a417799a35f1b0b684540">link</a> or you can create it manually.
If you want to stop the automation of the script, you can run the following command on the terminal:
```sh
launchctl unload /Library/LaunchAgents/com.launch.plug.and.play.mac.plist
```
<p align="right"><a href="#top">⇧</a></p>
Expand Down
35 changes: 35 additions & 0 deletions com.launch.plug.and.play.mac.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<!--
For more info on the .plist file visit:
- https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-BCIEDDBJ
- https://www.reddit.com/r/shortcuts/comments/qo9jfb/run_script_when_dockexternal_monitor_is_connected/
- https://apple.stackexchange.com/questions/336960/how-do-i-get-an-applescript-application-to-automatically-run-at-login
-->

<!-- Mac Studio Setup -->

<plist version="1.0">
<dict>
<key>Label</key>
<string>com.launch.plug.and.play.mac</string>
<key>ProgramArguments</key>
<array>
<!-- Use ~ to represent the user's home directory -->
<string>/usr/local/bin/PlugNPlayMac/PlugNPlayMac.sh</string>
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>LaunchOnlyOnce</key>
<true/>
<key>StartInterval</key>
<integer>120</integer>
<key>StandardErrorPath</key>
<string>/tmp/plug.and.play.mac.log</string>
<key>StandardOutPath</key>
<string>/tmp/plug.and.play.mac.log</string>
</dict>
</plist>

0 comments on commit 4907a04

Please sign in to comment.