i’m using two python scripts on my macbook that set an mqtt topic for a sleep sensor. i used to call the scripts with scenario, which didn’t work as reliably as i wished. i also tried sleepwatcher, but moved away from that because of lacking support for newer operating systems.
i’m getting pretty reliable results with hammerspoon now, calling the scripts when the mac awakes or goes to sleep.
wake.py
#!/usr/bin/env python3
import paho.mqtt.publish as publish
import sys
import ssl
import requests
import time
def wait_for_internet_connection(url='https://[HA-hostname]:[PORT]/local/custom_ui/floorplan/floorplan.css', timeout=5):
for x in range(0, 15):
try:
_ = requests.get(url, timeout=timeout)
return True
except requests.ConnectionError:
time.sleep(2)
pass
return False
def publish_message(topic, message):
print("Publishing to MQTT topic: " + topic)
print("Message: " + message)
auth = {
'username' : 'xxx',
'password' : 'xxx'
}
tls = {
'ca_certs':"/usr/local/etc/openssl/cert.pem",
'tls_version':ssl.PROTOCOL_TLSv1
}
publish.single(topic, message, hostname="[mqtt-hostname]", port=[PORT], auth=auth, tls=tls, retain=True)
if __name__ == '__main__':
if wait_for_internet_connection():
publish_message("ixbook/sleep/status", "stop")
else:
print("no connection")
sleep.py
#!/usr/bin/env python3
import paho.mqtt.publish as publish
import sys
import ssl
import requests
import time
def wait_for_internet_connection(url='https://[HA-hostname]:[PORT]/local/custom_ui/floorplan/floorplan.css', timeout=5):
for x in range(0, 15):
try:
_ = requests.get(url, timeout=timeout)
return True
except requests.ConnectionError:
time.sleep(2)
pass
return False
def publish_message(topic, message):
print("Publishing to MQTT topic: " + topic)
print("Message: " + message)
auth = {
'username' : 'xxx',
'password' : 'xxx'
}
tls = {
'ca_certs':"/usr/local/etc/openssl/cert.pem",
'tls_version':ssl.PROTOCOL_TLSv1
}
publish.single(topic, message, hostname="mqtt-hostname", port=[PORT], auth=auth, tls=tls, retain=True)
if __name__ == '__main__':
if wait_for_internet_connection():
publish_message("ixbook/sleep/status", "start")
else:
print("no connection")
this is the module that i use to call the scripts (embedded in a .sh file to call other services, too) with the hammerspoon caffeinate.watcher function:
sleep_watcher.lua
local sleepWatcher = require 'hs.caffeinate.watcher'
local function sleepWatch(eventType)
if (eventType == hs.caffeinate.watcher.systemWillSleep) then
hs.notify.show("Bye!", "", "")
hs.execute('/Users/ix/Library/Application\\ Support/LaunchBar/Actions/sleep.lbaction/Contents/Scripts/sleep.sh', true)
elseif (eventType == hs.caffeinate.watcher.systemDidWake) then
hs.notify.show("Wake sequence initiated!", "", "")
hs.execute('/Users/ix/Library/Application\\ Support/LaunchBar/Actions/wake.lbaction/Contents/Scripts/wake.sh', true)
end
end
return {
init = function()
sleepWatcher.new(sleepWatch):start()
end
}
if your mqtt broker is accessible from outside your network, this works anywhere, if the mac has an internet connection. it retries serveral times to connect to the net, to give the mac time after wakeup to connect to the network.
hammerspoon has a steep learning curve, but is a very usefull tool, that i don’t want to miss any more. something like this should also work for setting mqtt topics for your screen status or any other mac status or telemetry.