Read the statement by Michael Teeuw here.
Little magic mirror (but not a mirror)
-
@djgigabit Can’t take any credit for the coding, and this is just various bits of software hacked together. :beaming_face_with_smiling_eyes:
How to setup the Kindle and the script to grab the webpage came from Matt Healy (https://matthealy.com/kindle).
I’ve done a couple of things different. I added a pause in the script for the Kindle (about 4 seconds) after the curl command, just to allow the magic mirror page to finish generating. The other difference is, I’m running the script on the same Raspberry Pi as the magic mirror, not the Heroku site. The cron script is set to run every 5 minutes, which is fine for the info I’m displaying.
The magic mirror install is fairly normal, just needed to jam every thing into a small screen. Everything is ‘top_centre’ and then I just adjusted the margins to get it sitting nice. You have to start it in server mode ‘npm run server’ otherwise it will get upset that it does not have a screen to use.
An idle thought that occurred to me - instead of using a Raspberry Pi, you could run both bits of software on your everyday PC/laptop. If it’s not powered on (or in the building) when the Kindle asks for an update, it will fail to get a new image, so it will just display the last image it downloaded.
Hope this helps.
-
@SJK Oh nice, thank you! This is going to be helpful. The Fully browser I was trying to use didn’t like the webview version and there was no way to update on the Kindle or the Nexus 7 I was attempting to use so this is good info, thanks!
-
very cool use of broken gadgets. less for landfill and looks awesome
-
@djgigabit Here is my (sanatized) version of the index.js file from the web-to-kindle:
const express = require('express'); const path = require('path'); const puppeteer = require('puppeteer'); const execFile = require('child_process').execFile; const fs = require('fs'); const PORT = process.env.PORT || 3000; express() .use(express.static(path.join(__dirname, 'public'))) .set('views', path.join(__dirname, 'views')) .set('view engine', 'ejs') .get('/', async (req, res) => { const browser = await puppeteer.launch({ executablePath: '/bin/chromium-browser' }); const page = await browser.newPage(); await page.setViewport({ width: 600, height: 800 }); await page.goto(process.env.SCREENSHOT_URL || '<web address of magicmirror>'); await new Promise(r => setTimeout(r, 3000)); await page.screenshot({ path: '/home/<user>/screenshot.png', }); await browser.close(); await convert('/home/<user>/screenshot.png'); screenshot = fs.readFileSync('/home/<user>/screenshot.png'); res.writeHead(200, { 'Content-Type': 'image/png', 'Content-Length': screenshot.length, }); return res.end(screenshot); }) .listen(PORT, () => console.log(`Listening on ${PORT}`)); function convert(filename) { return new Promise((resolve, reject) => { const args = [filename, '-gravity', 'center', '-negate', '-extent', '600x800', '-colorspace', 'gray', '-depth', '6', '-alpha', 'remove', '-level', '50x100%', filename]; execFile('convert', args, (error, stdout, stderr) => { if (error) { console.error({ error, stdout, stderr }); reject(); } else { resolve(); } }); }); }
This is where I added the pause before it captures the screenshot. I also had to change the puppeteer.launch command as it was not a happy bunny running on a headerless server.
-
@SJK this is very cool! This method could be used for an eInk type display. It’s really making me think those old pi zeros could be very useful again.
-
This post is deleted!