第一部分——点子与镜子
作为一个男人,跟女友逛商城时,像是梅西百货那种的,难免会走神。我就是那号人,去年一月在纽约就发生过一回。长话短说。在我闲晃时我发现一面有灯光照明的镜子。我完全能自己做一面出来,而且比这更好。我想要属于我自己的魔镜!
一回到家,我开始构想我需要的东西:一面镜子,薄的那种,一个树莓派,一些木头和油漆,还需要大量空余时间。
关于镜子
普通的镜子是不行的。镜子是要那种单面透光那种,或更加精细功能的:后面屏幕黑屏时,它是一面镜子;而信息在屏幕上显示时就该像普通玻璃窗那样。
和警察局问询室内那面镜子原理一样,当只有一间房有光时,它就像一面镜子,其他时候它就是普通玻璃窗。
我所需要的是一面观察镜。现在,请相信我,当你问买玻璃的要一面观察镜时,会被反问一些奇怪的问题。他们那些人往往有更多新奇点子……嘿嘿,肮脏的思想永远是快乐的源泉。
终于我还是得到了一块不错的观察镜。开始找乐子吧!
第二部分——显示器
解决了镜子问题后,是时候为魔镜项目入手一台显示器了。
在为魔镜选择合适的显示器过程中,有一些纠结的决定。我是买一台新显示器还是捡一台呢?我需要什么尺寸?屏幕最薄会是多少?我如何移动控制按钮?屏幕是否够亮来盖过我的堂堂仪表?
因为我用显示器作为仪容之用,选择合适尺寸差不多就是选择合适的宽度(也就是镜子合适的高度)。在一些测量和尝试用胶带固定在墙上我想放置镜子的位置后,24英寸屏幕会是完美的选择。额外带来的好处是,绝大多数(便宜的)24英寸屏幕初始就带有1080P分辨率,正是我想在这个项目所使用的分辨率。
为了合适的屏幕类型和品牌,我几乎跑遍了方圆20公里内的电器铺。我敢肯定保安大叔在盯着我,而我正仔细检查所有屏幕背面和底部。
大多数品牌被立即否定了,因为它们的电源和视频连接线在背后。我需要转接线是在侧面的那种。
最后我选择了Iiyama显示器,它最接近我所希望的——价格便宜,边框窄小,简单触控按钮和正确转接器方向。
直到现在,我还是不清楚显示器外壳能否轻易被卸除,控制面板如何在显示器内部被连接上。销售人员不许我做出怪异的动作,打开显示器外壳,所以买到这台合适的显示器纯属运气。
我订购了一台24英寸Iiyama E2481HS-B1显示器。为确定显示器和镜子之间气密性良好,我拆下了外壳。在刚刚开箱就进行拆卸显示器够战战兢兢的,但……勉强成功。
这台Iiyama显示器的好处是,显示控制器(金属盒内的电子元件)为这面镜子的其他零件留下了足够的空间,而又保持了它原本的苗条外形。
实际的显示板仅有9毫米厚,而小小的边框也只是10毫米宽。加上显示控制器后,就是下列尺寸:556毫米x323毫米x46毫米(外加6毫米的镜子厚度)。这些尺寸构成了新的木头外壳尺寸。
第三部分——外壳
在量度新外壳所需尺寸后,就开始享受DIY的喜悦吧。我用松木做了个结实坚固的框架,用地板地脚线固定镜子和显示器的位置,那尺寸刚刚好(30毫米宽),还有圆角边框效果。
镜子很可能会发热,那就需要通风口了。此外,在外壳的背后还加了几个既美观又结实的挂点。
小剧透:产品最终重量6.5千克,由我做的两个挂载点所推测得来。
补充一下,我在外壳的底部开了条细缝作为电源线槽。
当然,它需要进行上色。在涂抹油灰(我在打磨抛光时后悔涂太多油灰了)、一些地漆及上土层后,新外壳完工。
有个木工小步骤我要去做的:我做了4个挂在块来安装显示器与镜子。现在准备好将它们上在镜框里面。
木工部分到此结束,进入魔镜的下一环节,安装硬件。
第四部分——安装硬件
魔镜开始成形。我订购了镜子,找到合适的显示器,完成打磨白色的外壳,是时候开始安装硬件了。
目前我手上有以下零件: · 显示器 · 树莓派 · 一条HDMI线(连接树莓派和显示器) · 一条USB转micro USB转接线(用来为树莓派供电) · 一条显示器电源线
但接着我遭遇到小小挫折。在找合适的显示器时,我完全没想到看看显示器有没有一个USB口,用来驱动树莓派。我以为现在的显示器都默认装有USB口,不过我错了,它没有。
这不是不能解决的问题,但我真心希望只用一条线来驱动魔镜。所以我只能将电源分为两条线,一条给显示器,一条给240伏USB降压器。补充一点,我希望用一条普通C13电源线就能驱动魔镜。
也就是说,我要做的是中间带有USB充电器的接插电源线。在翻了我几个闲置线材抽屉后,我找到了个旧USB充电器。
拆开充电器比想象中的容易,只要一点点焊接工序,一些胶和绝缘胶布即可。我要设法做个外观高大上的电源线。
我做了试运行,确保电源线正常工作。我将所有零件连接好,插好电源线,打开显示器。树莓派启动正常,USB充电器没有发热过量。不错!
接着组装所有零件。这次没有倒霉事件:所有东西完美吻合。
另一个阶段完成了,包括所有实体部分(除了还没把两颗螺丝钉在墙上)。进入戏肉的部分:安装树莓派。
Magic Mirror: Part V – Installing the Raspberry Pi
第五部分——安装树莓派
那么,做完所有硬件之后,就轮到安装树莓派了。要达到魔镜的所有需求,树莓派就要有以下功能:
· Wifi连接 · 屏幕旋转90度,符合照镜方向 · 本地网络服务维持界面 · 在全屏幕下运行的浏览器,用于显示界面
基本安装
因为Raspbian操作系统的灵活性和背后有开源社群支持,我就选了它。下载了操作系统映像后,就把它写入SD卡。
拷贝一个映像档需要很长时间,那么有三种选择:
用树莓派技术文档中提到的rdisk方法拷贝。 拿杯咖啡,坐下,在等待中享受咖啡因的感觉。 上面两者都选。
我选了3。完成拷贝后,我启动树莓派、登入,进入命令行的sudo raspi-config开始配置向导。在这个配置中,有几件重要事项需要配置:
· 确保系统启动到桌面(取代命令行模式或调试模式)。 · 调整时区,使魔镜显示正确时间。 · 在高级选项部分,确保显存超过128MB。 如果你想做和这个一样的镜子,尽管尝试选择所有其他选项。只是记住,如果选砸了,就再泡杯咖啡重装系统吧。
Wifi连接
我不想在魔镜上加任何多余的连接线,就选择了以Wifi连接因特网。安装Wifi接收器真的依赖频宽和种类,因此写下完全过程是多余的。有最好的替代吗?看看这个神奇的网站……
老实说,这部分安装确实很花时间。一旦装好了,就能工作正常。
旋转屏幕
魔镜在设计上是纵向肖像模式,所以我需要将屏幕顺时针旋转90度,最终显示分辨率为1080 x 1920。我曾担心这会是最大的问题,最终却很容易解决了。
树莓派的BIOS设置储存在系统启动分区中。在这分区中,有一个config.txt文件,载有所有设置。要旋转显示器,在这文件内加上以下一行代码:
display_rotate=1
要让显示器连接更加可靠,我就不解释为何加上下面允许HDMI线热插拔的代码了:
hdmi_force_hotplug=1
配置文件存盘后重启树莓派,我不禁会心一笑:这感觉真好,腰不疼颈不酸了!
网络服务器
要维持界面(很简单的一个网页),我需要在树莓派上Apache服务器。这在树莓派上是其中一个很常见的应用,安装过程简直行云流水。
首先我运行下列指令,确定我用的是最新系统软件。
sudo apt-get update && apt-get upgrade -y
现在是时候真的安装Apache了:
sudo apt-get install apache2 apache2-doc apache2-utils
完成了!就是所有这些。但要保证在服务器上能用到一些PHP脚本(以后会更多的),我也加上了PHP支持:
sudo apt-get install libapache2-mod-php5 php5 php-pear php5-xcache
又完成了!重启之后,网页服务器就挂载上线运行了!我在/var/www文件夹内放置了index.php文件,将浏览器首页指向树莓派的IP地址,发现成功了。
信息模式(kioskmode)
现在就是要确定树莓派能够显示我在信息模式(kioskmode)下用Chromium浏览器显示的网页。Chromium浏览器是个能在树莓派操作系统上运行的开源浏览器。
一如既往,安装很简单:
sudo apt-get install chromium x11-xserver-utils unclutter
但这一次,它需要一些额外设置,在信息模式下禁用屏幕保护和自动重启。我在/etc/xdg/lxsession/LXDE/autostart作了编辑,在前面加上了#号。
@xscreensaver -no-splash
另外我还加了以下代码:
@xset s off @xset -dpms @xset s noblank @chromium –kiosk –incognito http://localhost
这样就能完全禁用所有屏保功能,及Chromium浏览器在开机后自动启动,开启全屏模式并导向本地主页。
存盘并再一次重启,检查工作效果。树莓派并不是世界上最快的电脑,它需要花点时间,但最终测试页还是在旋转了90度的画面上显示出来。要得!
进入项目的最后部分,界面开发。
第六部分——界面开发
回顾一下,我买了合适的镜子、显示器,做了个新外壳,安装好硬件及配置完成树莓派,那就进入最后一步——界面开发。
需求和功能
我开始项目时,我发现不能通过镜子直接进行任何交互,要不然在铮亮的镜面上会抹上油脂和什么脏东西。但还有更重要的原因,还有别的更好设备可用于用户交互。我希望魔镜只是个被动信息来源。
而更更重要的是,镜子就是镜子,不应被大量(无用的)信息所填满。只有边上能用来作摘要性显示,给本帅哥留些足够自恋的空间吧。
这样我需要以下信息类别目录来满足我对信息的需求:
· 问候语 贴心问候,每日美好的开始。
· 天气 看到我穿的衬衫吗?不错吧!嗯?今天穿T恤衫不会鸡冻吧?
· 时钟和日历 现在赶时间吗?还有足够时间顾影自怜吧?
· 消息反馈 我只是担心自己形象帅不帅吗?还有别的需要上心吗?
当然,未来版本当中有大量的改进可能,现在列出的这些应该够用了。
基本安装
前面提过,程序界面不是一个在树莓派桌面上神奇的应用,仅仅是一个全屏幕网页。我能用HTML、CSS和Javascript开发外,还有一个额外的好处,在我将它放入魔镜之前,能在我的苹果电脑上开发测试。
在自己写的代码基础上,我用了一些开源库文件来优化它的运行速度:
像大多数网站那样,魔镜使用Jquery来简化DOM操作方式,对我这种懒人最为适用。
它对我在时间安排操作上帮助不少,尤其是在争分夺秒时更节省不少时间。
将RSS订阅用JSON数据转成javascript的方便工具。
将iCal数据转化为JSON。可惜这个库文件并不完美,需要一些额外的优化。
以上这些库文件,加上我自己的HTML和Javascript足够使我的镜子成精了。
设计
我的魔镜需要个酷炫设计。我本人是个严重果粉,那么在设计上要遵从苹果系的设计指标:
边框、倾角、阴影效果有时是用户界面厚重感的因素,甚至能盖过显示内容的光芒。所以,专注在内容设计,把用户交互界面摆在辅助位置上。
利用足够的实体空间,它是个重要内涵,在感官上更让人注意和易于理解。
怎么做到这一点?用Helvetica Neue字体,用天气图标对应显示天气信息。
镜子在背后没有光源时就只是一面镜子,用黑色背景是个重要设定。而为了有最好的对比度,显示内容字体应为白色,在加一些灰色阴影边缘,那灰度为50吧……
我大可以加上一些其他色彩,但目前为止我只想做到简洁的黑白界面。我可不想镜子比我的尊容还要出彩。(译者注:镜子:好吧,我不告诉你谁是世界上最帅的男人。镜子,碎。)
API设计
为了接收我想在镜子上显示的数据,我用了一些开源API和反馈代码。还有谁不太清楚什么是API,维基百科里面有详尽的解释:
“电脑操作系统(Operating system)’或‘程序库’提供给应用程序调用使用的代码。”
我心中的API就像你家的DVD播放器背后那样充满接口——如果你将其他设备连接到它的话,它就变得更加有用,这些接口本质上就是API。API让设备变得功能强大、有趣,尤其对我这种电脑狂人来说。
Openweathermap.org
Openweathermap有很好的API接口,能够免费得到天气预报信息。它允许你查询区域内的信息,定义你想要的信息类别。在这里我用了两个连接,一个是当前天气,另一个是预报天气。
iCal Calendar
iCloud允许你以iCal格式分享日历。因为javascript无法做到这一点(因为多站点脚本安全问题),我需要通过PHP代理服务器来开启数据。这其实很容易,只有三行代码而已:
$url = “https://p01-calendarws.icloud.com/ca/subscribe/1/mysupersecreticloudhash”; echo file_get_contents($url);
只需查询calendar.php就能将在同一个服务器内日历表在界面上显示出来。
前面说过的iCal语法分析编辑帮我把信息解析成有用信息。可是,iCloud在他们的反馈中用了一些非标准标签,我要添加额外的代码行来将代码解析为javascript文件。
NOS新闻订阅
新闻订阅只是用到了荷兰公共广播公司的RSS订阅功能。可是,他们不支持JSON格式数据,因此我用了FeedToJson插件来把RSS数据转为JSON格式的。
其他内容,例如当前日期与实践,还有问候语都只是一些简单的javascript语句。
自动更新
你看了这篇博客这么久,应该能接受更进阶的信息了吧。那么瞪大眼看下去吧……
在开发当中,我遇到了一个很不爽的境地,就是没有键盘和鼠标连在魔镜上的问题。如果我更新界面,就没有一个简单方法在魔镜上更新页面的方法。最简单直接的方法是重启整个树莓派,但让我在调试每个更新上花时间太多了。
我用GIT分布控制系统更新文件,而每个更新版本都有本身的哈希校验提交码,我用PHP就能读取出来。这启发了我再代码行内加上一个片段,将本地页面和刚刚开发的页面进行哈希比对。如果两者不符,程序将重新载入网页,显示最新版本。
我用以下PHP代码获取当前网页上的哈希校验码:
trim(`git rev-parse HEAD`)));
对比过程在javascript主文件内完成,但只有在HTML文件有当前版本的哈希校验值前提下才能实现:
var gitHash = ”;
现在,对比过程就很直观,每3秒进行一次:
(function checkVersion() { $.getJSON(‘githash.php’, {}, function(json, textStatus) { if (json) { if (json.gitHash != gitHash) { window.location.reload(); window.location.href=window.location.href; } } }); setTimeout(function() { checkVersion(); }, 3000); })();
所有这些神奇的操作,让更新魔镜界面变得简单。只需用SSH登入树莓派,进入合适的文件夹,然后处理一个git推送请求。
给我交出代码来!
得了得了……好奇了吧?所有代码在GitHub上都有。有件事情要说一声:代码很少标注,以面条式代码填充(译者注:就是大量复杂逻辑结构诸如if、when之类的条件语句,没想到老外还是有和国人程序猿一般的生物,反面例子啊),通篇都是TODO语句。哈,不怕晃晕菜的,尽管扎进去吧。
未来展望
魔镜还能做更多的功能,这是一个陆续发展过程。如有新功能上的建议,请不吝提供。让我知道你想在界面上的创意。不过请记住,少为美。:)
尽管有很多改进需要跟进,项目就总结到这儿吧。请关注我的博客,我会登出更多的照片来秀一下成品。
via org
2019-6-9 更新:
经过数年,无数 Maker 前赴后继地创造、加入到制作队伍,已经形成了一个专门 DIY 魔镜的社区。
网站不仅提供了完整的项目源码、一键安装脚本。还分享了项目中所用到的每个第三方模块,非常丰富,感觉已经发展成了一个平台化的系统软件。
https://talk.quwj.com/topic/17