Import into git

Pipeline #35 canceled with stages
Magic Kindle
Kindle 4 NT hacked to show the Magic Mirror 2 as screensaver.
![Work in progress demo](./demo.jpg)
Server Setup
* Install MagicMirror on localhost, for example in Docker:
* Install modules, for example a slideshow:
* Configure MagicMirror and its modules, for example as in `./magicmirror/config`. Avoid transitions and colors.
* Customize the CSS, for example as in `./magicmirror/css`.
* Install the dependencies of `./magiccapture` and Chromium.
* Make sure that the URL in `./magiccapture/index.js` points to the MagicMirror address.
* Set up a cron job to run `./magiccapture/`.
* Use a web server and make `./magiccapture/screenshot/screenshot.png` accessible to the network the Kindle will be connected to.
* Start MagicMirror, run the cron job and verify that a black/white PNG is being served.
Kindle Setup
* Get a Kindle 4. This setup was tested on firmware 4.1.3.
* Install the jailbreak and USBNetworking, the screensaver hack is not needed:
* Install the MKK and KUAL:
* Move `./magickindle/` to the Kindle at `/extensions/`.
* Change the URL in `./magickindle/bin/` so that it points to the web server.
* Optionally, customize the `rtcWakeup` time. The length of the interval has a significant impact on how long the battery lasts, as the Kindle only consumes power for the one minute wakeup.
* Navigate to the KUAL application on the Kindle and start the Magic Kindle extension.
* Press the power button to activate the screensaver which triggers the Magic Kindle script.
Enclose the Kindle in a fitting photo frame. Charge it once a month. If it does not turn on, press the power button for a minute and press it again for 10 seconds to force a reboot.

92.5 KB

magiccapture @ 61b27972
Subproject commit 61b2797294aad71b6685b1f7e406aded0105f502
# redirect stderr and stdout to file
exec >> /mnt/us/log 2>&1
# kill other instances of this script
ps -ef | grep '' | awk -v me=$me '$2 != me {print $2}' | xargs kill
echo "$(date) starting"
update_screensaver() {
echo "$(date) downloading screensaver"
#echo "$(date) enabling wifi"
#lipc-set-prop com.lab126.cmd wirelessEnable 1
for i in 1 2 3 4 5
curl "CHANGETHIS.png" --output /mnt/us/screensaver.png --fail --silent --show-error && break
sleep 10
# turning off wireless during ready to suspend causes issues with Kindle Wifi
# - the Kindle forgets the gateway, the configuration gets desynced,
# leading to the Kindle being connected but having no network
#echo "$(date) disabling wifi"
#lipc-set-prop com.lab126.cmd wirelessEnable 0
echo "$(date) updating screen"
eips -f -g /mnt/us/screensaver.png
lipc-wait-event -m com.lab126.powerd goingToScreenSaver,readyToSuspend | while read event
echo "$(date) event $event"
# throttle to 1/minute
NOW=$(date +%s)
if [ "$(($NOW - $LAST_UPDATE))" -ge 60 ]
# run in background so loop is not blocked
update_screensaver &
case "$event" in
# event looks like "goingToScreenSaver 7" so use a regex
echo "$(date) scheduling wakeup"
# must be called within 5s after readyToSuspend
# 60s until screensaver + 29min sleep
lipc-set-prop -i com.lab126.powerd rtcWakeup 1740
echo "$(date) waiting for next event"
<?xml version="1.0" encoding="UTF-8"?>
<name>Magic Kindle</name>
<menu type="json" dynamic="true">menu.json</menu>
"items": [
{"name": "Magic Kindle Screensaver",
"items" : [
{"name": "Start", "priority":0, "action": "bin/" }
Online Screensaver
------------------ v0.3
by peterson, via
thanks to the great folks in the Kindle developer corner
The Online Screensaver automatically fetches a new screensaver image from a
user-specified URL at a user-specified interval. If a screensaver is shown
at download time, the downloaded image will be displayed.
This extension supports updating the screensaver even when the Kindle is
asleep (obviously it won't work if you have really powered the Kindle down
by pressing the power button for many seconds). As such, it will use
additional battery as it will un-suspend your Kindle at the configured
intervals for one or two minutes.
The image should be in the correct resolution of your device, otherwise the
results may not look so pretty :-) The image also needs to be a "clean" png,
as otherwise you may only get a white screen (you can test whether an image
is working by calling "eips -f -g image.png" on your Kindle).
Possible use cases:
- download the latest weather report (this was the initial reason this
extension was developed), you need a server to automatically create this
image - see for example
- download the latest comic each day as your screensaver
- download inspirational images/messages each day
- etc
As of version 0.3, this extension has only been tested on a Kindle
Paperwhite 2 with WiFi. The auto-update script is currently only enabled
for devices with firmware 5 or newer (which should cover the devices that
actually have a front light).
If you get this extension to run on your device, please provide feedback
at where you will
also find the latest version.
How this script interacts with 3G models is also unknown.
It is recommended to test the extension manually prior to activating auto
updates. To do so, connect to your Kindle via SSH (ref. USBNet) and run
/mnt/us/extensions/onlinescreensaver/bin/ &
and then exit. If anything should go wrong, rebooting the Kindle should fix
any problem.
Either way, as usual please be advised that you are using this extension on
your own risk.
* You must have KUAL v2 or later installed.
* You must have linkss installed ("screensavers hack")
* By default, the extension copies the screensaver image to /mnt/us/linkss/screensavers
as bg_medium_ss00.png. On Paperwhite 2, you most likely already have a
file of that name - if you don't want it overwritten, please make a
backup. It is advisable to only have one screensaver image, as otherwise
the results may become unpredictable.
Unzip the downloaded file into the extensions folder (/mnt/us/extensions
when using SSH, otherwise the extensions folder at root of the Kindle volume
when connected to your PC).
Edit onlinescreensaver/bin/, all available options are described
here. Note that you MUST use an editor that supports Unix line endings. On
Windows, use e.g. the free notepad++ application.
Run KUAL and enter the "Online-Screensaver" section. Here you have an item
to update the screensaver right away (one time), and you can also enable or
disable the auto-download.
It is recommended to disable auto-updates prior to deleting the folder
from the extensions directory.
var config = {
address: "", // any
port: 8080,
ipWhitelist: [], // any
language: "de",
timeFormat: 24,
units: "metric",
serverOnly: true,
modules: [
module: "MMM-Trello",
position: "bottom_bar",
config: {
api_key: "",
token: "",
list: "",
reloadInterval: 1000 * 60 * 60,
updateInterval: 1000 * 60 * 5,
animationSpeed: 0,
showTitle: true,
showDescription: true,
isCompleted: false,
showLineBreaks: true,
showDueDate: false,
showChecklists: false,
showChecklistTitle: false,
wholeList: false,
module: "MMM-ImagesPhotos",
position: "fullscreen_below",
config: {
opacity: 1.0,
animationSpeed: 0,
updateInterval: 60000,
module: "MMM-DateOnly",
position: "top_right",
config: {
showWeek: false,
dateFormat: "dddd, LL",
module: "MMM-PublicTransportHafas",
position: "top_right",
config: {
stationID: "",
stationName: "",
updatesEvery: 60 * 15,
direction: "",
interval: 1000 * 60 * 15,
timeToStation: 0,
timeInFuture: 180,
showColoredLineSymbols: false,
useColorForRealtimeInfo: false,
showAbsoluteTime: true,
marqueeLongDirections: false,
showTableHeaders: false,
maxReachableDepartures: 2,
maxUnreachableDepartures: 0,
fadeReachableDepartures: false,
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}
body {
color: #fff;
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
body {
margin: 40px 30px 40px 30px;
position: absolute;
height: calc(100% - 80px);
width: calc(100% - 60px);
/* images slideshow */
.fullscreen.below {
display: flex;
flex-direction: column;
justify-content: center;
/* hafas */
.pthBWLineSign {
background-color: initial;
font-size: initial;
font-weight: initial;
color: #fff;
margin: 0;
.pthWrapper header {
display: none;
.pthDirectionCell {
min-width: 0;
padding: 0;
.pthDelay {
display: none;
.pthTable {
float: right !important;
width: auto !important;
.pthDirectionCell::before {
content: "nach ";
/* general */
.module {
margin-bottom: 15px;
html {
cursor: none;
overflow: hidden;
background: #000;
::-webkit-scrollbar {
display: none;
body {
margin: 60px;
position: absolute;
height: calc(100% - 120px);
width: calc(100% - 120px);
background: #000;
color: #aaa;
font-family: "Roboto Condensed", sans-serif;
font-weight: 400;
font-size: 2em;
line-height: 1.5em;
-webkit-font-smoothing: antialiased;
* Default styles.
.dimmed {
color: #666;
.normal {
color: #999;
.bright {
color: #fff;
.xsmall {
font-size: 15px;
line-height: 20px;
.small {
font-size: 20px;
line-height: 25px;
.medium {
font-size: 30px;
line-height: 35px;
.large {
font-size: 65px;
line-height: 65px;
.xlarge {
font-size: 75px;
line-height: 75px;
letter-spacing: -3px;
.thin {
font-family: Roboto, sans-serif;
font-weight: 100;
.light {
font-family: "Roboto Condensed", sans-serif;
font-weight: 300;
.regular {
font-family: "Roboto Condensed", sans-serif;
font-weight: 400;
.bold {
font-family: "Roboto Condensed", sans-serif;
font-weight: 700;
.align-right {
text-align: right;
.align-left {
text-align: left;
header {
text-transform: uppercase;
font-size: 15px;
font-family: "Roboto Condensed", Arial, Helvetica, sans-serif;
font-weight: 400;
border-bottom: 1px solid #666;
line-height: 15px;
padding-bottom: 5px;
margin-bottom: 10px;
color: #999;
sup {
font-size: 50%;
line-height: 50%;
* Module styles.
.module {
margin-bottom: 30px;
.region.bottom .module {
margin-top: 30px;
margin-bottom: 0;
.no-wrap {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.pre-line {
white-space: pre-line;
* Region Definitions.
.region {
position: absolute;
.region.fullscreen {
position: absolute;
top: -60px;
left: -60px;
right: -60px;
bottom: -60px;
pointer-events: none;
.region.fullscreen * {
pointer-events: auto;
.region.right {
right: 0;
text-align: right;
} {
top: 0;
} .container {
margin-bottom: 25px;
.region.bottom .container {
margin-top: 25px;
} .container:empty {
margin-bottom: 0;
}, {
left: 50%;
-moz-transform: translateX(-50%);
-o-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
},, {
top: 100%;
.region.bottom {
bottom: 0;
.region.bottom .container:empty {
margin-top: 0;
.region.bottom.left {
bottom: 100%;
} {
width: 100%;
text-align: center;
.region.third, {
width: 100%;
text-align: center;
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
.region.upper.third {
top: 33%;
} {
top: 50%;
.region.lower.third {
top: 66%;
.region.left {
text-align: left;
.region table {
width: 100%;
border-spacing: 0;
border-collapse: separate;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment