WEBVTT
00:00.000 --> 00:01.567
Hi everyone! I'm Mehmet Tekman,
00:01.567 --> 00:02.483
and I'm here to talk to you
00:02.483 --> 00:03.700
about using Amazon Kindles
00:03.700 --> 00:05.040
as a productivity dashboard for
00:05.040 --> 00:07.359
your various projects.
00:07.359 --> 00:09.519
In a nutshell, you describe your machines,
00:09.519 --> 00:11.317
your commands, and your schedules
00:11.317 --> 00:13.120
in an Org-Mode file,
00:13.120 --> 00:14.933
and then you just initialize
00:14.933 --> 00:16.960
your Kindle devices.
00:16.960 --> 00:18.367
These devices are asleep
00:18.367 --> 00:19.117
most of the time,
00:19.117 --> 00:20.720
but they wake up at scheduled times
00:20.720 --> 00:22.033
to retrieve content
00:22.033 --> 00:24.800
from the centralized server.
00:24.800 --> 00:27.599
Content can be Org mode and Emacs-based,
00:27.599 --> 00:29.500
or it can be from Web content,
00:29.500 --> 00:42.840
or it can just be static images and WAV.
00:42.840 --> 00:45.600
If you, like me, struggle to
00:45.600 --> 00:46.833
keep your life under tabs,
00:46.833 --> 00:48.300
or find it very hard to separate
00:48.300 --> 00:49.417
your work life from your home life,
00:49.417 --> 00:51.283
then you, like me, likely need
00:51.283 --> 00:52.917
some kind of passive background service
00:52.917 --> 00:54.083
that reminds you of where you are
00:54.083 --> 00:55.267
and what you are supposed to be doing.
00:55.267 --> 00:56.960
Even if it's just a sign saying,
00:56.960 --> 00:58.640
"You're at home! Relax!"
00:58.640 --> 01:00.400
An Amazon Kindle is perfect for this.
01:00.400 --> 01:01.717
In a nutshell, it's a cheap
01:01.717 --> 01:03.117
black and white e-ink device
01:03.117 --> 01:03.800
that can go for weeks
01:03.800 --> 01:05.033
without needing a single charge.
01:05.033 --> 01:06.767
Every year, Amazon brings out
01:06.767 --> 01:07.983
an incrementally better model,
01:07.983 --> 01:09.333
which makes the old devices obsolete,
01:09.333 --> 01:11.067
and you can find these older models
01:11.067 --> 01:13.360
for 5 euros on second-hand websites.
01:13.360 --> 01:15.360
Plus it runs Linux, has WiFi networking,
01:15.360 --> 01:16.987
and has a dedicated forum of hackers
01:16.987 --> 01:19.200
for getting the most out of the device.
01:19.200 --> 01:20.366
Some drawbacks of this is that
01:20.366 --> 01:22.799
the device often comes with unwanted bloat:
01:22.799 --> 01:24.050
over-the-air updates,
01:24.050 --> 01:25.833
it phones home to Amazon regularly,
01:25.833 --> 01:27.033
it has a secret microphone
01:27.033 --> 01:27.983
embedded in the device,
01:27.983 --> 01:29.433
and it has a bunch of creepy
01:29.433 --> 01:30.633
seemingly interdependent
01:30.633 --> 01:31.439
background processes,
01:31.439 --> 01:34.083
where killing one kind of kills the others
01:34.083 --> 01:36.560
risking that you will break the device.
01:36.560 --> 01:37.799
But this is where the community
01:37.799 --> 01:38.883
really shines through,
01:38.883 --> 01:40.483
since the friendly (and not-so-friendly)
01:40.483 --> 01:41.583
users (and developers)
01:41.583 --> 01:43.200
from the MobileRead forums have pretty much
01:43.200 --> 01:44.560
scraped out a good portion of the
01:44.560 --> 01:46.960
harmful Amazon scripts from the device.
01:46.960 --> 01:48.550
Some of the devices even use
01:48.550 --> 01:49.483
Awesome Window Manager,
01:49.483 --> 01:50.800
meaning you can really play around
01:50.800 --> 01:51.620
with the existing system
01:51.620 --> 01:52.633
without having to create
01:52.633 --> 01:54.233
your own X11 server.
01:54.233 --> 01:55.377
This then empowers users
01:55.377 --> 01:57.600
to display whatever they want on the device.
01:57.600 --> 01:59.040
One project that really got this going
01:59.040 --> 02:00.560
was the Kindle-Dash dashboard from
02:00.560 --> 02:02.320
Pascal Widdershoven, who really refined a
02:02.320 --> 02:03.483
lot of the internal scripts
02:03.483 --> 02:05.439
to stabilize the device.
02:05.439 --> 02:06.600
However, the project then
02:06.600 --> 02:07.650
puts the onus on the device
02:07.650 --> 02:08.560
to retrieve the data from
02:08.560 --> 02:09.950
somewhere else over the internet,
02:09.950 --> 02:10.753
and so you still need to
02:10.753 --> 02:11.440
generate the content
02:11.440 --> 02:13.200
and place it on the web somewhere.
02:13.200 --> 02:14.640
Plus you need to do this and manage it
02:14.640 --> 02:17.360
for every Kindle device that you have.
02:17.360 --> 02:18.500
Kindle-Sync, however,
02:18.500 --> 02:19.867
is an entirely different beast,
02:19.867 --> 02:21.800
albeit one that builds off of the works
02:21.800 --> 02:23.440
of the aforementioned projects.
02:23.440 --> 02:24.800
It assumes that instead of just having
02:24.800 --> 02:26.050
one Kindle device around
02:26.050 --> 02:27.133
that you wish to re-purpose
02:27.133 --> 02:28.080
for productivity purposes,
02:28.080 --> 02:28.983
that you actually have
02:28.983 --> 02:30.117
multiple Kindle devices
02:30.117 --> 02:30.794
that you want to manage
02:30.794 --> 02:32.720
and configure in tandem.
02:32.720 --> 02:33.633
Everything is managed
02:33.633 --> 02:35.667
from a dedicated server (or a raspberry pi)
02:35.667 --> 02:37.440
which distributes jobs to multiple Kindles,
02:37.440 --> 02:39.519
running on different update timers.
02:39.519 --> 02:40.786
These timers are all managed
02:40.786 --> 02:41.486
from the server,
02:41.486 --> 02:43.017
and all the Kindle device has to do is:
02:43.017 --> 02:45.200
to wake up, power on the WiFi,
02:45.200 --> 02:47.280
receive some media, display the media, and
02:47.280 --> 02:49.680
receive a barebones RTC sleep request.
02:49.680 --> 02:51.040
Then it sleeps for the requested time,
02:51.040 --> 02:52.800
consuming no power, whilst displaying the
02:52.800 --> 02:55.200
desired media. That is maybe 10 seconds
02:55.200 --> 02:57.599
of awake time between each request.
02:57.599 --> 02:58.933
Cron does not actually run
02:58.933 --> 02:59.933
on the Kindle device itself,
02:59.933 --> 03:01.600
simply because it does not reliably work.
03:01.600 --> 03:04.050
All of this is handled by the server.
03:04.050 --> 03:05.599
With the server-client model,
03:05.599 --> 03:08.000
it also tries to restrict Amazon access.
03:08.000 --> 03:09.517
SSH keys are shared
03:09.517 --> 03:11.217
only from the client to the server,
03:11.217 --> 03:12.517
but not from the server to the client,
03:12.517 --> 03:13.920
so the Kindle cannot connect
03:13.920 --> 03:16.319
to the Raspberry Pi without a password.
03:16.319 --> 03:18.033
IPtables rules are also set
03:18.033 --> 03:19.483
so that the Kindle cannot phone home
03:19.483 --> 03:20.667
to Amazon, and the connections
03:20.667 --> 03:23.200
are restricted to just the LAN.
03:23.200 --> 03:24.820
So I got very curious at one point
03:24.820 --> 03:26.133
and decided to see how long
03:26.133 --> 03:27.599
a Kindle could last on a single charge
03:27.599 --> 03:28.560
in such an arrangement,
03:28.560 --> 03:30.640
so that every 15 minutes for 18 hours,
03:30.640 --> 03:31.599
I tested the device
03:31.599 --> 03:32.959
by sending a media item
03:32.959 --> 03:35.200
and recording the battery level.
03:35.200 --> 03:36.159
The Kindle doesn't seem to
03:36.159 --> 03:36.959
report the battery level
03:36.959 --> 03:37.760
very continuously,
03:37.760 --> 03:39.040
but at discrete percentages,
03:39.040 --> 03:39.840
so that you could end up with
03:39.840 --> 03:42.159
a graph that looks like this.
03:42.159 --> 03:43.617
Assuming you have half the charge,
03:43.617 --> 03:45.200
and use it once every hour -
03:45.200 --> 03:48.319
it will drop by 10% battery in 76 hours,
03:48.319 --> 03:49.760
which is roughly three days.
03:49.760 --> 03:50.640
It's hard to extrapolate
03:50.640 --> 03:52.400
with only three good summarized data points,
03:52.400 --> 03:53.519
of which the number of requests
03:53.519 --> 03:54.879
per battery level appear to diminish
03:54.879 --> 03:56.640
as shown in the table below,
03:56.640 --> 03:58.560
but the final result yields 76 requests
03:58.560 --> 04:00.799
with an average loss of 0.5% battery life
04:00.799 --> 04:02.273
per request. Which is not bad!
04:02.273 --> 04:04.400
Assuming you do a request every 2 hours
04:04.400 --> 04:06.000
from 8am to 8pm,
04:06.000 --> 04:07.040
and let it sleep at night,
04:07.040 --> 04:09.040
then that's approximately 6 requests a day,
04:09.040 --> 04:10.400
which could easily last a device
04:10.400 --> 04:11.280
for a month.
04:11.280 --> 04:12.586
The ksync script does
04:12.586 --> 04:13.200
essentially everything:
04:13.200 --> 04:14.799
from generating and fetching the media,
04:14.799 --> 04:16.720
to initializing all Kindle devices,
04:16.720 --> 04:18.160
generating the server cronjobs,
04:18.160 --> 04:19.199
log report summaries,
04:19.199 --> 04:20.400
editing the config tables,
04:20.400 --> 04:21.199
and much more.
04:21.199 --> 04:22.880
The media operations are comparatively
04:22.880 --> 04:23.680
much more complex
04:23.680 --> 04:25.280
and encompass a few media use cases
04:25.280 --> 04:26.400
such as fetching the weather
04:26.400 --> 04:28.560
(though only from Open Weather Maps)
04:28.560 --> 04:30.000
and retrieving Google Calendar views
04:30.000 --> 04:32.000
by week, month, agenda, and four day view.
04:32.000 --> 04:33.199
You can retrieve Org-Mode data
04:33.199 --> 04:34.639
from an Emacs instance on the server,
04:34.639 --> 04:35.360
which in my case
04:35.360 --> 04:36.720
I produce views for an agenda
04:36.720 --> 04:39.360
or a sparse tree of my main projects file.
04:39.360 --> 04:41.120
Finally we have gallery and wavfile,
04:41.120 --> 04:42.240
which are static resources
04:42.240 --> 04:44.000
which will never change once generated.
04:44.000 --> 04:45.199
The idea is that you feed it
04:45.199 --> 04:46.400
text and an image location,
04:46.400 --> 04:47.040
and it generates
04:47.040 --> 04:48.720
a Kindle-compatible image
04:48.720 --> 04:51.280
using imagemagick as a backend for it.
04:51.280 --> 04:52.240
In the case of the wavfile,
04:52.240 --> 04:54.160
it uses espeak on the backend.
04:54.160 --> 04:55.280
The below is summarized
04:55.280 --> 04:56.317
from the help-me text
04:56.317 --> 04:57.199
in the main ksync file,
04:57.199 --> 04:58.160
but essentially, you need to
04:58.160 --> 04:59.919
define your config in the CSV files,
04:59.919 --> 05:01.440
which we talk about in the next section;
05:01.440 --> 05:03.120
initialize all your Kindle devices,
05:03.120 --> 05:04.720
i.e. copy over SSH keys,
05:04.720 --> 05:06.160
kill all the unnecessary services,
05:06.160 --> 05:07.840
and prime them for media collection;
05:07.840 --> 05:08.720
and ensure that you have
05:08.720 --> 05:10.080
all your static media generated
05:10.080 --> 05:11.440
and fetchable; and finally
05:11.440 --> 05:12.720
you then refresh the scheduling
05:12.720 --> 05:14.240
on the server.
05:14.240 --> 05:15.759
Okay, so this is all good and well,
05:15.759 --> 05:17.039
and we now know what the server does
05:17.039 --> 05:18.400
and how to probe and inspect it -
05:18.400 --> 05:19.759
but how does the server generate
05:19.759 --> 05:21.120
much of the content?
05:21.120 --> 05:22.080
So a lot of the content
05:22.080 --> 05:23.360
will be dynamically generated,
05:23.360 --> 05:24.639
meaning it cannot be cached
05:24.639 --> 05:26.720
and is likely to change from hour to hour.
05:26.720 --> 05:28.400
The media content that is generated here
05:28.400 --> 05:29.759
are mostly PNG images
05:29.759 --> 05:30.567
and have a timestamp
05:30.567 --> 05:32.320
embedded in their filenames.
05:32.320 --> 05:33.520
The Emacs-specific content
05:33.520 --> 05:34.560
consists of a few views,
05:34.560 --> 05:36.000
namely the org-gcal views,
05:36.000 --> 05:37.600
org-agenda, and org-calories --
05:37.600 --> 05:39.520
essentially anything that Emacs can display
05:39.520 --> 05:42.000
and that you want to capture into an image.
05:42.000 --> 05:43.360
Emacs can't (as far as I know)
05:43.360 --> 05:44.639
render graphics in a headless way,
05:44.639 --> 05:45.600
so what we do instead
05:45.600 --> 05:48.240
is run Emacs in a dummy minimal X11 session
05:48.240 --> 05:50.080
via "xvrb-run."
05:50.080 --> 05:51.680
From inside, you can take screenshots
05:51.680 --> 05:52.233
as you would in
05:52.233 --> 05:53.440
a normal desktop environment,
05:53.440 --> 05:54.400
but with the benefit that
05:54.400 --> 05:56.479
you don't actually need to invoke a desktop
05:56.479 --> 05:58.560
or interfere with an existing one.
05:58.560 --> 05:59.840
The minimal elisp shown here
05:59.840 --> 06:00.720
is all that is required
06:00.720 --> 06:02.400
to output your desired image from Emacs
06:02.400 --> 06:04.479
and configure it for the Kindle environment.
06:04.479 --> 06:05.360
On the web side of things,
06:05.360 --> 06:06.400
we don't really need to invoke
06:06.400 --> 06:07.520
a dummy X11 session
06:07.520 --> 06:09.120
because Chromium can run headless
06:09.120 --> 06:09.919
and can be controlled
06:09.919 --> 06:11.600
by the node library "puppeteer"
06:11.600 --> 06:13.039
to render dynamic content,
06:13.039 --> 06:14.560
focus on regions of the webpage,
06:14.560 --> 06:16.080
and take snapshots.
06:16.080 --> 06:17.600
The static content comprises
06:17.600 --> 06:19.600
of two types: images and audio.
06:19.600 --> 06:21.520
The content is accessed by a key,
06:21.520 --> 06:22.560
in this case Batman,
06:22.560 --> 06:23.600
and the content information
06:23.600 --> 06:25.199
is given by the "--extra" parameter
06:25.199 --> 06:26.960
which describes either or both
06:26.960 --> 06:30.880
an image and text.
06:30.880 --> 06:32.248
Okay, so now we have content,
06:32.248 --> 06:33.600
how do we schedule this content
06:33.600 --> 06:34.960
to appear on our desired machines
06:34.960 --> 06:36.400
at desired times?
06:36.400 --> 06:37.759
Everything is run via cron.
06:37.759 --> 06:38.720
So previously we saw that
06:38.720 --> 06:40.880
we only needed the tables MACHINES.csv,
06:40.880 --> 06:43.440
COMMANDS.csv, and multiple TIME_*.csv tables
06:43.440 --> 06:44.880
for the shell script to work.
06:44.880 --> 06:46.479
But Org-Mode does this far easier,
06:46.479 --> 06:47.919
since you can just have everything
06:47.919 --> 06:49.039
in the same file,
06:49.039 --> 06:50.720
and with the helper minor-mode,
06:50.720 --> 06:51.360
manage everything
06:51.360 --> 06:53.120
from a single Org-Mode document.
06:53.120 --> 06:55.120
Here I have 4 kindles and their shortnames.
06:55.120 --> 06:56.160
Yes, I even have a Kindle
06:56.160 --> 06:57.520
hanging outside my door.
06:57.520 --> 06:58.960
I have 11 defined commands
06:58.960 --> 07:00.800
which represent the views I want to see,
07:00.800 --> 07:02.319
and there are 4 timetables I use,
07:02.319 --> 07:02.800
but you can have
07:02.800 --> 07:04.319
everything on one, if you like.
07:04.319 --> 07:05.360
Rows are machine names,
07:05.360 --> 07:06.800
and columns are corresponding hours
07:06.800 --> 07:07.840
at which they run.
07:07.840 --> 07:09.440
Trust me, it's easier to configure
07:09.440 --> 07:10.960
repeating tasks just by repeating them
07:10.960 --> 07:12.720
multiple times, because at least this way,
07:12.720 --> 07:13.680
it's human readable,
07:13.680 --> 07:14.880
and the script which converts these
07:14.880 --> 07:15.759
to a cronjob
07:15.759 --> 07:18.800
collapses the repeating tasks by itself.
07:18.800 --> 07:20.560
The ksync script can be called
07:20.560 --> 07:23.120
from within the config.org file
07:23.120 --> 07:24.683
using this convenient
07:24.683 --> 07:26.960
use-package declaration.
07:26.960 --> 07:28.319
All that one needs to do
07:28.319 --> 07:30.560
is to configure the ENVIRONMENT_VARIABLES
07:30.560 --> 07:32.880
by setting them in this table
07:32.880 --> 07:34.479
where you set the repo name,
07:34.479 --> 07:36.160
the config directory,
07:36.160 --> 07:37.599
where the media shall go,
07:37.599 --> 07:38.960
and the server IP,
07:38.960 --> 07:39.919
although this can be
07:39.919 --> 07:41.360
automatically detected.
07:41.360 --> 07:42.240
The package allows you
07:42.240 --> 07:43.440
to export your tables
07:43.440 --> 07:46.720
by running C-c C-c on them,
07:46.720 --> 07:49.199
and allows you to update all the jobs
07:49.199 --> 07:52.319
related to each of your clients.
07:52.319 --> 07:53.759
You can also initialize clients
07:53.759 --> 07:55.120
using this package --
07:55.120 --> 07:56.479
for either all of them
07:56.479 --> 07:58.479
or individual clients --
07:58.479 --> 07:59.599
and the package comes with
07:59.599 --> 08:01.120
some convenience functions
08:01.120 --> 08:02.720
to do this automatically
08:02.720 --> 08:06.720
for all tables in the buffer.
08:06.720 --> 08:08.319
With this, I want to say a big thank you
08:08.319 --> 08:09.840
to Takaaki Ishikawa
08:09.840 --> 08:11.520
for his fantastic "org-tree-slide"
08:11.520 --> 08:12.879
presentation package.
08:12.879 --> 08:14.136
To Pascal Widdershoven
08:14.136 --> 08:15.803
and David Hamp-Gonsalves,
08:15.803 --> 08:16.633
for their fantastic
08:16.633 --> 08:17.840
kindle-dash repositories,
08:17.840 --> 08:19.903
for which some of my internal Kindle scripts
08:19.903 --> 08:20.720
are derived from.
08:20.720 --> 08:22.160
Also a big thanks to the friendly
08:22.160 --> 08:23.520
and not-so-friendly users and hackers
08:23.520 --> 08:24.960
in the MobileRead forums.
08:24.960 --> 08:25.919
And finally, a big thanks
08:25.919 --> 08:26.960
to the Emacs community
08:26.960 --> 08:28.270
and the conference organizers.
08:28.270 --> 08:31.120
Thank you! [captions by Mehmet]