Hi Andreas,
I updated my BTT and noticed that you added BTT to Shortcuts, thank you. However, I think it would be great if I can set up a trigger on changing focus mode (ex. when I activate/deactivate focus "work" or any others). Though, it's possible to use automation on both iPhone and iPad that allows to set up running any shortcuts actions when any focus is on/off.
Seconding this. I use keyboard shortcuts to activate specific apps. It would be great if I could conditionally set a group of apps based on a focus mode.
1 Like
Bump - I think this would be super awesome!
Bump - Would be a game changer for me
if you just need to trigger if focus mode is enabled/disabled, you can use the
"Trigger on Script Output Change" with this script:
return get_number_variable("SystemDoNotDisturbState");
1 Like
While this is already great, it does not trigger when changing from one focus mode to the other, which would be my intended use case. Thanks anyways!
If you need the focus mode name you can achieve that with some scripting however it
- requires BTT 4.728 alpha
- BTT must have full disk access in System Settings => Privacy & Security => Full Disk Access
Then you can use this script (modify the bottom condition to check for your desired focus mode)
let jax = `
var app = Application.currentApplication()
app.includeStandardAdditions = true
function getJSON(path) {
const fullPath = path.replace(/^~/, app.pathTo('home folder'))
const contents = app.read(fullPath)
return JSON.parse(contents)
}
function run() {
let focus = "No focus" // default
const assert = getJSON("~/Library/DoNotDisturb/DB/Assertions.json").data[0].storeAssertionRecords
const config = getJSON("~/Library/DoNotDisturb/DB/ModeConfigurations.json").data[0].modeConfigurations
if (assert) { // focus set manually
const modeid = assert[0].assertionDetails.assertionDetailsModeIdentifier
focus = config[modeid].mode.name
} else { // focus set by trigger
const date = new Date
const now = date.getHours() * 60 + date.getMinutes()
for (const modeid in config) {
const triggers = config[modeid].triggers.triggers[0]
if (triggers && triggers.enabledSetting == 2) {
const start = triggers.timePeriodStartTimeHour * 60 + triggers.timePeriodStartTimeMinute
const end = triggers.timePeriodEndTimeHour * 60 + triggers.timePeriodEndTimeMinute
if (start < end) {
if (now >= start && now < end) {
focus = config[modeid].mode.name
}
} else if (start > end) { // includes midnight
if (now >= start || now < end) {
focus = config[modeid].mode.name
}
}
}
}
}
return focus
}
`
let focusModeName = await runJAX(jax);
// check for the localized focusmode name
if(focusModeName == "Sleep") {
return true;
} else {
return false;
}
Thanks for the script!
I have not yet gotten it to work reliable enough for me, but I may be doing something wrong
Anyway, I think I'm looking for a more integrated solution that basically replicates the automation provided by the Shortcuts app on iOS.
I found myself here because I want to change my background/wallpaper based on the focus mode. Like you can do on iOS. It's a great feature.
I see the post above by Andreas, but I'm not sure how to do what I want. Of course, this as a native feature of BTT would be absolutely awesome.
If we wanted to use this for multiple Focus modes, would the best way be to create multiple scripts – one for each mode where we want a different action depending on the true
result?
probably yes, but then all scripts should call the same function to determine the state and that function should do some debouncing / caching. I‘ll give it a try later!
Ah I think a better solution to this use case is to run the script periodically and update a variable if the focus mode has changed. Then you can use the " Variable Value Did Change" trigger:
Example Preset:
exported_triggers.bttpreset (13.3 KB)
Here is a slightly updated script REQUIRES BTT 4.789
async function checkFocusState() {
let focus = "No focus";
let assertions = JSON.parse(readFile("~/Library/DoNotDisturb/DB/Assertions.json"));
let modeConfigurations = JSON.parse(readFile("~/Library/DoNotDisturb/DB/ModeConfigurations.json"))
let config = modeConfigurations.data[0].modeConfigurations;
let manualFocus = assertions?.data[0]?.storeAssertionRecords;
if(manualFocus) {
const modeid = manualFocus[0]?.assertionDetails?.assertionDetailsModeIdentifier
if(modeid) {
focus = config[modeid]?.mode?.name
}
} else {
const date = new Date
const now = date.getHours() * 60 + date.getMinutes()
for (const modeid in config) {
const triggers = config[modeid].triggers.triggers[0]
if (triggers && triggers.enabledSetting == 2) {
const start = triggers.timePeriodStartTimeHour * 60 + triggers.timePeriodStartTimeMinute
const end = triggers.timePeriodEndTimeHour * 60 + triggers.timePeriodEndTimeMinute
if (start < end) {
if (now >= start && now < end) {
focus = config[modeid].mode.name
}
} else if (start > end) { // includes midnight
if (now >= start || now < end) {
focus = config[modeid].mode.name
}
}
}
}
}
let previousFocusMode = await get_string_variable("last_focus_mode");
if(previousFocusMode != focus) {
await set_string_variable({variableName: "last_focus_mode", to: focus})
}
return focus;
}
Then in the variable value did change you can have some if conditions:
in 4.890 I added a advanced trigger condition variable "focus_mode". BTT requires full disk access for this to work. (System Settings => Security & Privacy )
1 Like