My script looks for certain bluetooth state criterias (if it's turned On and if there's no device connected) through the first loop and then sleeps 10 seconds to allow the user to change the bluetooth state and then checks again the same criterias before executing a prompt.
What I don't understand is that when I run the code and change the state before the wait period (10 seconds) end, it still runs the code inside the second if statement.
def bluetoothLoop():
while True:
def bluetooth_msg():
BT_state = subprocess.run(['''system_profiler SPBluetoothDataType'''], shell=True, capture_output=True, encoding="utf", errors="ignore")
BT_state = BT_state.stdout
sound = "Blow"
title = "TURN OFF BLUETOOTH"
message = "Wasting energy"
if "State: On" in BT_state and not " Connected:" in BT_state:
time.sleep(10)
if "State: On" in BT_state and not " Connected:" in BT_state:
command = f'''
osascript -e 'display notification "{message}" with title "{title}" sound name "{sound}"'
'''
os.system(command)
bluetooth_msg()
CodePudding user response:
You're not refreshing the state after you sleep for 10 seconds. Try
if "State: On" in BT_state and not " Connected:" in BT_state:
time.sleep(10)
BT_state = subprocess.run(['''system_profiler SPBluetoothDataType'''], shell=True, capture_output=True, encoding="utf", errors="ignore")
BT_state = BT_state.stdout
if "State: On" in BT_state and not " Connected:" in BT_state:
command = f'''
osascript -e 'display notification "{message}" with title "{title}" sound name "{sound}"'
'''
os.system(command)
You can probably even clean up your code by doing
def bluetoothLoop():
BT_state = subprocess.run(['''system_profiler SPBluetoothDataType'''], shell=True, capture_output=True, encoding="utf", errors="ignore")
BT_state = BT_state.stdout
def bluetooth_msg():
sound = "Blow"
title = "TURN OFF BLUETOOTH"
message = "Wasting energy"
command = f'''
osascript -e 'display notification "{message}" with title "{title}" sound name "{sound}"'
'''
os.system(command)
while "State: On" in BT_state and not " Connected:" in BT_state:
bluetooth_msg()
time.sleep(10)
BT_state = subprocess.run(['''system_profiler SPBluetoothDataType'''], shell=True, capture_output=True, encoding="utf", errors="ignore")
BT_state = BT_state.stdout
Beware I didn't run the code above, so you may need to tweak it a little.
CodePudding user response:
You run the subprocess
to get the BT_state
before the sleep but you don't run it again after the sleep so the variable BT_state
is not updated. Effectively you are checking the same thing twice.
I have refactored your code below to separate out the different pieces in the hope that it is easier to see what is going on.
import subprocess
import time
def check_bt_status():
output = subprocess.check_output(["system_profiler",
"SPBluetoothDataType"])
return all([b"Bluetooth Power: On" in output,
b"Connected: Yes" not in output])
def show_msg(title, message, sound):
apple_script = (f'display notification "{message}"'
f'with title "{title}" '
f'sound name "{sound}"')
subprocess.check_output(["osascript", "-e", apple_script])
def bluetooth_loop():
while True:
if check_bt_status():
show_msg("TURN OFF BLUETOOTH", "Wasting energy", "Blow")
time.sleep(10)
if __name__ == "__main__":
bluetooth_loop()
Putting the BT state logic in a separate method means that if you need to change that logic, then you only need to change it in one place.