Tool for building simple automations
Just got a new Samsung phone, and they have this nifty app that I think is quite powerful, quite feasible to implement extensibly, and is overall just petty nice. GNOME should have such a thing
Heads up I'll make this very long because it's a very well designed feature of my phone and that just blew me away and really inspired me. I've crystalized an idea of how GNOME could make use of this in my head, so I want to write it all down so that maybe future me, or maybe someone else motivated, could implement this.
They call it "Modes and Routines", but we should probably call it something shorter... "Automations"? Or just "Routines"?
It's similar to #66, I suppose, but as far as I can tell it makes no attempt to spy on apps in ways that Wayland wouldn't allow (i.e. know when a user is in a text box), nor does it have a programming language component attached to it. But it can still be used to build very useful automations
So first I'll cover "Routines". A routine is baically this kind of pattern: If Then Finally . If multiple triggers are specified, they must all be true for the actions to fire. The triggers can either be continuous (the device is currently in some state) or oneshot (something happened). You can have at most one oneshot trigger in the list of triggers. Actions can either be reversible (i.e. change some setting, then change it back later) or not (open an app). The Finally block only appears if all the triggers are continuous, and if at least one action is reversible (but we should remove this second requirement and just show an empty Finally block). The Finally block defaults to just undoing everything it can from the Then block. That covers the rules, so here's the actual behavior: whenever all the necessary triggers are met for a routine, the actions in the Then block are executed. When the triggers stop being met, the Finally block is executed.
So for example, a Routine could look like: If (Location is at home) Then (turn on ringer) Finally (Return ringer settings to how they were before). Let's say your phone is on vibrate and you come home. It'll automatically turn on the ringer. Then later when you leave the house it'll go back to vibrate. Quite powerful. By the way, it can determine location both by Location Services and also supplementing that by detecting if you're connected to a given WiFi network.
They also have some system-level integration with do-not-disturb. Basically you can configure DND differently depending on what routine activated it. For instance, if you have a routine that activates whenever you're at work that turns on DND, you can turn on a "but allow repeated callers" setting to let through people insistently calling you. Alternatively, if you have a routine that you manually activate whenever you go to the movies that (among other things) turns on DND, you can turn off "but allow repeated callers" and instead add a list of the couple people that must absolutely reach you in case of emergency. Samsung can also do things like suppressing do not disturb or a muted ringer for just one notification.
So for another example, a routine can look like: If (ringer is muted) and (I'm getting a call from ) and (I'm not at work) Then (ring anyway)
Samsung's implementation also has these things called "Modes", but they're not clearly distinguished from Routines. They're essentially a special case of a routine that you can start/stop manually, but they also can be started/stopped automatically same as a routine. I think the distinction is mostly for the user's mental model. Modes are also get toggles in places like the quick settings panel, and status icons in the system status bar.
I suppose you can think of a mode as a custom trigger for a routine (it can be used as one). Samsung just also implicitly creates a routine for any given mode with its trigger set to that mode, but I think that's confusing and we should just leave Modes as a way to define custom triggers. Modes can be turned on/off manually, optionally with a duration step which they'll turn off on their own. They can also turn themselves on automatically, reusing the continuous triggers from a routine.
Examples of Modes include: Sleep mode, Driving mode, Work mode, Relax mode, Theater mode. You can also make custom modes. The pre-defined modes I listed here have really nice setup flows, though, which try to guide you through some common things. For instance, when you first look at sleep mode they walk you though picking a sleep/wake time, optionally making an alarm (through an integration with the clock app), turning on and customizing DND, and then suggest some more settings (dark mode, dimming the screen, turning on night light, etc). All very slick and positive experience
Ok so translating this all into implementation for GNOME. Basically we need an app that has a framework to put together routines and modes, and given a steam of events figure out when/how to trigger various actions. This logic should be pretty generic and simple
Then the app can implement triggers and actions that get plugged into this logic. Many can already just be built into the app. The app can monitor system services on its own (i.e. NetworkManager sends dbus signals whenever the WiFi network you're connected to changes) use that to put together some basic triggers. There is also the trivial trigger of "whenever the user manually activates this routine", which should be possible from the Routines app and maybe even gnome-shell. The app can also have some basic actions, for instance by changing gsettings (example: Dark mode on/off), or changing the volume, or disconnecting from WiFi, opening an app, opening a file, running a command, etc. Lots of things can go here.
Now here's the extensibility bit which turns this from kinda useful to extremely powerful. We can define some dbus interfaces that apps can implement if they want to integrate with this Routines thing.
One interference would be for providing triggers. It would need to list the types of triggers the app supports (alongside human-readable names, icon, description, etc). If one of these app-specific triggers is chosen by the user, the Routines app can call the dbus interference to pop open a configuration UI (much in the same way we pop open portals!). Once the configurating is done, then the dbus call returns some unique ID string, which Routines will use as its trigger. If whatever conditions configured in the external app were met, then the app simply tells Routines "hey trigger got triggered" over dbus and later "<unique ID got un-triggered" (if it's a continuous trigger) and that's it. Tada! Completely custom triggers in just a couple dbus methods
Custom actions will work in much the same way. Third-party app exposes a list of action types via dbus. Routines is used to pick one. It then asks the third-party app to build a customized action of selected type, and the app pops open a dialog just like a portal does. Once a customized action is built, a unique string is handed back to Routines. Then whenever routines wants to trigger an action, it just gives the unique ID back to the app, asks to either do it or reverse it (if the action is reversible) and the app can do whatever it wants in response
Custom apps can then use this interface to implement arbitrarily complex automations. For instance, there could be a Home Assistant client app on your device that you can link to your Home Assistant instance. It'll then expose whatever smart light switches or smart buttons or whatever that you own as triggers, and the various things you can do with your smart home devices as actions.
So final example of how this would all work together. I have home assistant set up, and the client app is installed on my GNOME Phone. I open "Automation" or "Routines" or whatever, and make a new routine. I add a trigger under If, and it pops open a list of all the various triggers. I pick "Location", which opens a customization UI that lets me choose that I want a oneshot trigger that fires whenever I'm leaving a place. I select my home as the place, and my home's WiFi network as a way to improve accuracy. I now have a partial routine: If (I leave home) Then <???>. So now I add an action. Again, another dialog with a list of actions pops up, and this time I scroll down to the part of the list with custom actions provided by apps. I pick "Home Assistant", and it shows a sub-list of just the home assistant actions (obtained via dbus). I pick "Turn off lights". This makes a dbus call asking the Home Assistant app to customize its turn-off-lights action, which makes Home Assistant open a dialog parented to the build-a-routine window (using the same API that portals do). In this dialog, I pick the lights I want to turn off (all of them), and home assistant gives back some unique token. This token will now be used as the action. I now have a cohesive Routine: If (I leave home) Then (turn off all the lights via Home Assistant). Let's fast forward to the next morning. I'm walking out of my house on my way to work. This eventually disconnects my device from my home WiFi, which makes NetworkManager send a dbus broadcast that gets picked up by the routines app. It scans through the list of routines and finds one that's based on location. So it re-checks that location and finds that yes I really did leave home. It then triggers the actions: it dbus-activates the home assistant app and tells it to perform the action . Home assistant looks this up in its own database, and finds that it's an action to turn off lights, and it's set to operate on all lights. So home assistant does this and turns off all the lights. I've now used GNOME to automate all my lights turning off when I leave the house.
Hopefully I demonstrated here how these relatively simple things add up to being so so so powerful. And with just a tiny bit of integration into the desktop environment (i.e. by exposing toggles for modes into quick settings, and exposing manually-activatable triggers somewhere like a power menu ala Android used to, or next to the quick settings ala Android today, or in the calendar area instead of notifications) GNOME could become a lot "smarter" with relatively minimal effort.