Adapt power management to changes in the environment.
MoccaFaux can be used to prevent the activation of screen savers and power-saving modes when certain conditions are met. It was inspired by caffeine, but is much more flexible.
In fact, MoccaFaux is a scheduler that executes commands (called watches), looks at their exit codes and then decides whether to execute another set of commands (called tasks):
-
execute all watches (such as
:listening-to-music
or:system-backup-is-running
) and record their exit codes -
assign exit code of each watch to one or more tasks (such as
:keep-computer-awake
or:disable-screensaver
) -
update state of each task:
-
:active
if any of the assigned watches returned a non-zero exit code -
:idle
in any other case
-
-
in case the state of a task differs from its previous state, execute a command depending on its new state
-
wait, rinse and repeat the above
On exit, MoccaFaux tries to execute the :idle
command for
every task. This usually works, but as it happens in a critical phase
during shutdown, you should not rely on this behaviour.
All watches, tasks and commands as well as their number can be defined by the user.
This makes MoccaFaux very flexible and it could probably be used for other tasks as well, such as compiling an application when the files in a directory change. In practice, however, you might be better off using dedicated software and APIs such as Gulp.watch and inotify.
Please note that the scheduler's timing may drift and repetitions will be dropped when the computer is suspended or under extremely high load – so please do not use MoccaFaux when your main concerns are high reliability or repeatability.
To be honest, controlling screensaver and power management of Linux desktops is quite a mess. Despite some conventions, there seems to be no universal standard, and applications and tools often resort to kludges.
I wanted to keep my computer awake when syncing large files, but there seemed to be no solution that would survive the ravages of time. So I decided that disabling power management and screensaver was my best option and started to write MoccaFaux.
As this application was conceived as a substitue for caffeine, I originally called it Muckefuck (pronounced [ˈmʊkəfʊk]). This is a colloquial German term for coffee substitute.
On second thought, English speakers might reason that this name contains a certain "bad" word (it doesn't). I liked the name, though, so I changed it to Mocca faux, which some believe to be the French origin of Muckefuck.
You need an installation of Java. I currently use OpenJDK 11, but any Java version from 8 probably works just fine:
# Debian-based systems
sudo apt-get install default-jre
Simply download a pre-compiled JAR file from the release section and
copy moccafaux-x.x.x.jar
to a place of your liking.
To compile MoccaFaux, you'll also need Git and Leiningen:
# Debian-based systems
sudo apt-get install git leiningen
Then clone the repository and compile the application:
git clone https://github.com/mzuther/moccafaux.git
cd moccafaux
lein clean && lein uberjar
Finally, copy target/uberjar/moccafaux.jar
to a place of your liking.
First, you have to create an options file. When you are done, open a shell and locate to the MoccaFaux directory. Then execute:
# setting MALLOC_ARENA_MAX bounds virtual memory, see
# https://issues.apache.org/jira/browse/HADOOP-7154
MALLOC_ARENA_MAX=4 java -jar moccafaux.jar
You will probably start MoccaFaux automatically or from a menu.
When problems occur, however, run it in a shell. It prints status
messages to stdout
that will help you with problem fixing.
By default, MoccaFaux adds an icon to the system tray bar. This
icon has three states and changes depending on whether no, some or
all of the defined tasks are :idle
.
MoccaFaux reads its settings from the file
$HOME/.config/moccafaux/config.edn
. As the file extension suggests,
settings are expected to be in Clojure's EDN format. You can think
of it as an enhanced version of JSON (use ;
for comments).
To get started, use a copy of config-SAMPLE.edn
(found in the
repository's root directory) and edit to taste. For it to work, you
have to disable your system's own power management and install
some tools:
# Debian-based systems (pgrep, xautolock and xset)
sudo apt-get install procps xautolock x11-xserver-utils
# optional stuff (pactl and zpool)
sudo apt-get install pulseaudio-utils zfsutils-linux
The settings file constitutes of a map with three key-value pairs:
{
:settings {
:add-traybar-icon true
:probing-interval 60
}
:tasks {
;; see below
}
:watches {
;; see below
}
}
I suggest that you restrict key names to ASCII characters, hyphens and numbers. However, Clojure does not force you to do so.
Set this to false
if you do not want MoccaFaux to add an icon to
the system tray bar.
Sets the interval in seconds for repeating the watch commands. I have found 60 seconds to be a good trade-off between resource usage and response time. But this interval is not restricted in any way, so if you set it to one second (great for testing), all watches will be checked once per second. Let's just hope that your computer can keep up with this ...
For something to actually happen, you have to define at least one task. Tasks are basically switches that are turned on and off by MoccaFaux.
They are defined in a map with two keys (:active
and :idle
), which
in turn consist of maps containing three keys (:message
, :command
and :fork
):
:tasks {
:sleep {
:active {
:message "allow computer to save energy"
:command "xautolock -time 10 -locker 'systemctl suspend' -detectsleep"
:fork true
}
:idle {
:message "keep computer awake"
:command "xautolock -exit"
:fork false
}
}
;; and so on ...
}
When any of the assigned watch commands returns a non-zero exit
code, the command defined under :active
is executed. Otherwise, the
:idle
command is executed.
When you start MoccaFaux, each task will be executed once according to the current state of your watches.
This is the actual command and is executed in a shell environment
compatible to the Bourne shell (sh -c "your | commands && come ; here"
).
This way, you can use your beloved pipes and logical tests.
Note: backslashes have to be quoted by doubling (\\
).
MoccaFaux normally runs a command and waits for it to exit.
However, some commands need to continue running in the background. In
such a case, set :fork
to true
. Note that forked commands are not
monitored, so you have to kill them manually when watch states change.
When MoccaFaux exits, forked commands should be killed
automatically, but this is not guaranteed.
Use :message
to describe what is happening in plain text. It will
be shown on the command line and may help you with debugging (or
understanding the EDN file in a year or so).
Watches are commands that are run periodically. When their exit code changes, they may trigger the toggling of a task.
Watches are defined in a map of three keys (:enabled
, :command
and :tasks
):
:watches {
:video {
:enabled true
:command "pgrep -l '^(celluloid|skypeforlinux|vlc)$'"
:tasks {
:dpms true
:sleep true
}
}
;; and so on ...
}
Set to false
if you do not want a watch to be executed. Use this
when you only need it occasionally or want to keep your time-proven
settings where you can easily find them in the future.
This is identical to its twin in tasks except that it must exit (MoccaFaux needs the exit code), so forking is not supported.
Map of keys naming the tasks that should be updated whenever the
state of this watch changes. Each key's value should be set to
true
.
You may also set a key to false
. This is identical to not adding
the task to this map.
- Martin Zuther: maintainer
Copyright (c) 2020-2021 Martin Zuther and contributors
This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.
Thank you for using free software!