diff options
| author | schneefux <schneefux+commit@schneefux.xyz> | 2020-01-26 12:02:24 +0100 |
|---|---|---|
| committer | schneefux <schneefux+commit@schneefux.xyz> | 2020-01-26 15:55:18 +0100 |
| commit | 8b1a693f9f8492f9a9e49aef6b3a64ace9e50e9d (patch) | |
| tree | 75e165d64e6758113151d10e871563ae428bc773 | |
| download | magic-kindle-8b1a693f9f8492f9a9e49aef6b3a64ace9e50e9d.tar.gz magic-kindle-8b1a693f9f8492f9a9e49aef6b3a64ace9e50e9d.zip | |
| -rw-r--r-- | README.md | 33 | ||||
| -rw-r--r-- | demo.jpg | bin | 0 -> 94737 bytes | |||
| -rw-r--r-- | magiccapture/eink_cmap.gif | bin | 0 -> 377 bytes | |||
| -rw-r--r-- | magiccapture/index.js | 21 | ||||
| -rw-r--r-- | magiccapture/package-lock.json | 317 | ||||
| -rw-r--r-- | magiccapture/package.json | 14 | ||||
| -rw-r--r-- | magiccapture/run.sh | 4 | ||||
| -rw-r--r-- | magickindle/bin/start.sh | 58 | ||||
| -rw-r--r-- | magickindle/config.xml | 12 | ||||
| -rw-r--r-- | magickindle/menu.json | 9 | ||||
| -rw-r--r-- | magicmirror/config/config.js | 73 | ||||
| -rw-r--r-- | magicmirror/css/custom.css | 58 | ||||
| -rw-r--r-- | magicmirror/css/main.css | 243 |
13 files changed, 842 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..536f2f2 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +Magic Kindle +=== + +Kindle 4 NT hacked to show the Magic Mirror 2 as screensaver. + +<img src="demo.jpg" height="300" /> + +Server Setup +--- + + * Install MagicMirror on localhost, for example in Docker: https://magicmirror.builders/ + * Install modules, for example a slideshow: https://github.com/roramirez/MMM-ImagesPhotos + * 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/run.sh`. + * 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: https://wiki.mobileread.com/wiki/Kindle4NTHacking + * Install the MKK and KUAL: https://www.mobileread.com/forums/showthread.php?t=203326 + * Move `./magickindle/` to the Kindle at `/extensions/`. + * Change the URL in `./magickindle/bin/start.sh` 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. diff --git a/demo.jpg b/demo.jpg Binary files differnew file mode 100644 index 0000000..499c8ba --- /dev/null +++ b/demo.jpg diff --git a/magiccapture/eink_cmap.gif b/magiccapture/eink_cmap.gif Binary files differnew file mode 100644 index 0000000..4f51ee2 --- /dev/null +++ b/magiccapture/eink_cmap.gif diff --git a/magiccapture/index.js b/magiccapture/index.js new file mode 100644 index 0000000..0db29a6 --- /dev/null +++ b/magiccapture/index.js @@ -0,0 +1,21 @@ +const path = require('path'); +const puppeteer = require('puppeteer-core'); + +async function main() { + const browser = await puppeteer.launch({ + executablePath: 'google-chrome-stable', + args: ['--no-sandbox'], + }) + const page = await browser.newPage(); + await page.setViewport({ + width: 600, + height: 800 + }); + await page.goto(`http://localhost:8080`, { waitUntil: 'networkidle0' }); + await page.waitFor(2000); + await page.screenshot({path: 'screenshot/color.png'}); + + await browser.close(); +} + +main().then(console.log).catch(console.error) diff --git a/magiccapture/package-lock.json b/magiccapture/package-lock.json new file mode 100644 index 0000000..d2aa5e0 --- /dev/null +++ b/magiccapture/package-lock.json @@ -0,0 +1,317 @@ +{ + "name": "screenshot", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "requires": { + "pend": "~1.2.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", + "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" + }, + "puppeteer-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-2.0.0.tgz", + "integrity": "sha512-xgg8hLm7VIiwoYRZtgXNy0gf9IKCA/WyT5Rm5RqkDc7mm4bJMeESmzP+YWyl+X/c1CSOuCy4WWnnC+9T+DKgCQ==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^3.0.0", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "requires": { + "fd-slicer": "~1.0.1" + } + } + } +} diff --git a/magiccapture/package.json b/magiccapture/package.json new file mode 100644 index 0000000..2704ca8 --- /dev/null +++ b/magiccapture/package.json @@ -0,0 +1,14 @@ +{ + "name": "screenshot", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "author": "schneefux", + "license": "UNLICENSED", + "dependencies": { + "puppeteer-core": "^2.0.0" + } +} diff --git a/magiccapture/run.sh b/magiccapture/run.sh new file mode 100644 index 0000000..354c8b6 --- /dev/null +++ b/magiccapture/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash + +node index.js +convert screenshot/color.png -filter LanczosSharp -distort Resize 600x800 -colorspace sRGB -background black -gravity center -extent 600x800! -grayscale Rec709Luminance -colorspace sRGB -dither Riemersma -remap eink_cmap.gif -quality 75 -define png:color-type=0 -define png:bit-depth=8 screenshot/screenshot.png diff --git a/magickindle/bin/start.sh b/magickindle/bin/start.sh new file mode 100644 index 0000000..4b260ad --- /dev/null +++ b/magickindle/bin/start.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# redirect stderr and stdout to file +exec >> /mnt/us/log 2>&1 + +# kill other instances of this script +me=$$ +ps -ef | grep 'start.sh' | 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 + do + curl "CHANGETHIS.png" --output /mnt/us/screensaver.png --fail --silent --show-error && break + sleep 10 + done + # 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 +} + +LAST_UPDATE=0 +lipc-wait-event -m com.lab126.powerd goingToScreenSaver,readyToSuspend | while read event +do + echo "$(date) event $event" + + # throttle to 1/minute + NOW=$(date +%s) + if [ "$(($NOW - $LAST_UPDATE))" -ge 60 ] + then + # run in background so loop is not blocked + update_screensaver & + fi + LAST_UPDATE=$NOW + + case "$event" in + # event looks like "goingToScreenSaver 7" so use a regex + readyToSuspend*) + 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 + ;; + goingToScreenSaver*) + ;; + esac + echo "$(date) waiting for next event" +done; + diff --git a/magickindle/config.xml b/magickindle/config.xml new file mode 100644 index 0000000..5f28dd6 --- /dev/null +++ b/magickindle/config.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<extension> + <information> + <name>Magic Kindle</name> + <version>0.1</version> + <author>schneefux</author> + <id>MagicKindle</id> + </information> + <menus> + <menu type="json" dynamic="true">menu.json</menu> + </menus> +</extension> diff --git a/magickindle/menu.json b/magickindle/menu.json new file mode 100644 index 0000000..5248ce6 --- /dev/null +++ b/magickindle/menu.json @@ -0,0 +1,9 @@ +{ + "items": [ + {"name": "Magic Kindle Screensaver", + "items" : [ + {"name": "Start", "priority":0, "action": "bin/start.sh" } + ] + } + ] +} diff --git a/magicmirror/config/config.js b/magicmirror/config/config.js new file mode 100644 index 0000000..3896e1f --- /dev/null +++ b/magicmirror/config/config.js @@ -0,0 +1,73 @@ +var config = { + address: "0.0.0.0", // 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;} diff --git a/magicmirror/css/custom.css b/magicmirror/css/custom.css new file mode 100644 index 0000000..6e940b2 --- /dev/null +++ b/magicmirror/css/custom.css @@ -0,0 +1,58 @@ +.normal, +.dimmed, +header, +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; +} diff --git a/magicmirror/css/main.css b/magicmirror/css/main.css new file mode 100644 index 0000000..84f8c4d --- /dev/null +++ b/magicmirror/css/main.css @@ -0,0 +1,243 @@ +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; +} + +.region.top { + top: 0; +} + +.region.top .container { + margin-bottom: 25px; +} + +.region.bottom .container { + margin-top: 25px; +} + +.region.top .container:empty { + margin-bottom: 0; +} + +.region.top.center, +.region.bottom.center { + left: 50%; + -moz-transform: translateX(-50%); + -o-transform: translateX(-50%); + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); +} + +.region.top.right, +.region.top.left, +.region.top.center { + top: 100%; +} + +.region.bottom { + bottom: 0; +} + +.region.bottom .container:empty { + margin-top: 0; +} + +.region.bottom.right, +.region.bottom.center, +.region.bottom.left { + bottom: 100%; +} + +.region.bar { + width: 100%; + text-align: center; +} + +.region.third, +.region.middle.center { + 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%; +} + +.region.middle.center { + top: 50%; +} + +.region.lower.third { + top: 66%; +} + +.region.left { + text-align: left; +} + +.region table { + width: 100%; + border-spacing: 0; + border-collapse: separate; +} |
