基于树莓派的智能魔镜
本帖最后由 ky123 于 2018-1-31 14:05 编辑首先,感谢E络盟官方提供的树莓派,谢谢大佬~~给大佬鞠躬,哈哈哈
---------------------------------无耻之极的分割线-----------------------------------------------
一、项目名称:pandora,基于树莓派的智能魔镜
1.原理介绍:(其实原理很简单~~)
树莓派魔镜显示原理其实很简单,就是一块原子镜,也就是双面镜,后面放上一块屏幕,因为屏幕上面现实的字的亮度高于前面,所以,字就透过来了,同时,没有字的地方设置为黑色背景,于是人们还可以把他当作一面普通的镜子。至于显示的东西,是使用chrome浏览器的kiosk模式,(该模式说白了就是全屏模式,没有了上面的状态栏。),开机启用kiosk模式,并打开一个网页,网页的指向的地址,是本机部署的一个NodeJS服务器。
系统架构图:
现在网上有很多的魔镜帖子,但是大多数服务器用的都是老外写的那个代码,神烦(不过写的很D),所以就打算自己撸一个,于是就开始了苦逼的代码之路。
2.功能介绍:
1)显示时间,天气的信息
2)根据编写的问候语规则,动态生成问候语,比如节日问候、天气转凉穿衣提醒、日常问候等。
3)人脸识别功能,系统已知的人员使用镜子时,摄像头会对使用者进行人脸识别生成动态问候语,例如,你好,薇薇
4)实时新闻抓取,支持自己编写新闻抓取插件,系统现内置OSChina新闻,新浪科技新闻,历史上的今天三种。
5)屏幕休眠唤醒,使用时唤醒屏幕。
3.模块介绍:
NodeJS服务器使用ExpressJS框架,前端模板使用EJS,系统分为:前端模块、新闻模块、JOB任务模块、问候语生成器、摄像头人脸识别模块。
前端模块:前端模块最为简单,主要是编写显示样式,使用的是bootstrap前端框架,EJS代码较少,主要是JS逻辑比较多,主要代码:
EJS模板代码:<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="//cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div>
<div class="clock">
<div id="clock-date" class="clock-fonts-color-size-date">星期* ****年**月**日</div>
<div id="clock-hm" class="clock-fonts-color-size-hm">** : **</div>
<div id="clock-sec" class="clock-fonts-color-size-sec">**</div>
</div>
<div class="weather">
<div id="todaytemp" class="weather-today">*℃~*℃</div>
<div id="todayweather" class="weather-today">多云</div>
<div id="todaywind" class="weather-today">西北风 3-4级</div>
<div id="nowtemp" class="weather-today">实时温度:5℃(5分钟前更新)</div>
<div id="airstatus" class="weather-today">空气质量:优(30)</div>
</div>
</div>
<div class="welcome" id = "welcome">
你好,陌生人。
</div>
<div class="news" id = "news">
<div id="title" class="title"></div>
<div id="abstract" class="abstract"><div>
</div>
<!-- javascripts -->
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script src="//cdn.bootcss.com/jquery-backstretch/2.0.4/jquery.backstretch.min.js"></script>
<script src="/javascripts/index.js"></script>
<script src="/javascripts/socket.io/socket.io.js"></script>
</body>
</html>
JS代码:/*
* @Author: Nicot
* @Date: 2016-03-29 23:12:03
* @Last Modified by: Nicot
* @Last Modified time: 2018-01-09 20:50:36
*/
//落日时间
var ss = {
ssh: 18,
ssm: 0
};
var sr = {
srh: 6,
srm: 0
};
jQuery(document).ready(function() {
$.backstretch("/images/black.png");
$.updateDateTime(document);
setInterval(function() {
//更新时间
$.updateDateTime(document);
},1000);
var socket = io();
socket.on('connect', function() {
socket.emit('hello', '你大爷');
});
socket.on('welcome', function(msg) {
var welcome = document.getElementById('welcome');
var date = new Date();
console.log(msg);
var welcomeMsg = JSON.parse(msg);
if(welcomeMsg.type == 'come' || welcomeMsg.type == 'connect') {
if(date.getHours() >= sr.srh && date.getHours() < 9) {
welcome.innerText = '早上好,' + welcomeMsg.msg + ',开心快乐每一天哦!';
} else if(date.getHours() >= 12 && date.getHours() < ss.ssh) {
welcome.innerText = '下午好,' + welcomeMsg.msg + '^_^';
} else if(date.getHours() >= 9 && date.getHours() < 12) {
welcome.innerText = '上午好,' + welcomeMsg.msg + '^_^';
} else {
welcome.innerText = '晚上好,' + welcomeMsg.msg + '^_^';
}
} else {
welcome.innerText = welcomeMsg.msg;
}
});
socket.on('weather', function(msg) {
$.updateWeather(document, msg);
});
socket.on('news', function(msg) {
var title = document.getElementById('title');
var abstract = document.getElementById('abstract');
var news = JSON.parse(msg);
title.innerText = '[' + news.type + ']' + news.title;
abstract.innerText = news.abstract == '' ? '' : news.abstract.substring(0, 100) + '...';
});
});
(function($){
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"H+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o) : (("00" + o).substr(("" + o).length)));
return fmt;
}
$.updateDateTime = function(doc) {
var clockhm = doc.getElementById('clock-hm');
var clocksec = doc.getElementById('clock-sec');
var clockdate = doc.getElementById('clock-date');
var weekArr = ['一', '二', '三', '四', '五', '六', '日'];
var week = weekArr;
clockdate.innerText = new Date().Format("yyyy年MM月dd日") + " " + "星期"+ week;
clockhm.innerText = new Date().Format("HH:mm");
clocksec.innerText = new Date().Format("ss");
}
$.updateWeather = function(doc, msg) {
var weather = JSON.parse(msg);
if(weather.type == 'nowWeather') {
var nowtemp = doc.getElementById('nowtemp');
var updateTime = new Date(weather.updateTime);
nowtemp.innerText = '实时温度:' + weather.weather.tmp + '℃ 天气:' + weather.weather.cond_txt;
} else if(weather.type == 'nowAir') {
var airstatus = doc.getElementById('airstatus');
var qlty = weather.air.qlty == undefined ? '极好': weather.air.qlty;
airstatus.innerText = '空气质量:' + qlty + '(' + weather.air.aqi + ')';
} else if(weather.type == 'todayWeather') {
var todaytemp = doc.getElementById('todaytemp');
var todayweather = doc.getElementById('todayweather');
var todaywind = doc.getElementById('todaywind');
var today = weather.forecast;
todaytemp.innerText = today.tmp_min + '℃ ~ ' + today.tmp_max + '℃';
ss.ssh = parseInt(today.ss.split(':'));
ss.ssm = parseInt(today.ss.split(':'));
sr.srh = parseInt(today.sr.split(':'));
sr.srm = parseInt(today.sr.split(':'));
var date = new Date();
if(date.getHours() > ss.ssh && date.getMinutes() > ss.ssm) {
todayweather.innerText = today.cond_txt_n;
} else {
todayweather.innerText = today.cond_txt_d;
}
todaywind.innerText = today.wind_dir + ' ' + today.wind_sc + '级';
}
}
})(jQuery);JS代码还引入了了socket.io的客户端,用于实时通信。
新闻模块:
新闻模块先包含三种新闻抓取,分别是OSChina、新浪科技、历史上的今天,新闻模块可扩展,只要添加相应的抓取代码即可。网页爬虫使用:cheerio插件。
JOB任务模块:
任务模块主要是系统的一些功能的定时任务,如:定时天气情况、空气情况、实时天气的获取与推送,问候语的定时生成与推送、新闻的定时抓取与推送、摄像头模块的检测与重启等,定时任务使用:node-schedule模块。
问候语生成器:
问候语生成器使用vm模块,动态编译用户定义的规则,生成问候语,用于支持节日问候、天气提醒等功能。规则代码例子:/*
* @Author: Nicot
* @Date: 2018-01-03 00:25:31
* @Last Modified by: Nicot
* @Last Modified time: 2018-01-07 15:28:56
*/
module.exports = {
random: ['weather', 'festival'],
connect: [
{
expression: 'true',
characters: ['很高兴见到你!', '你来啦~', '恭喜您成功连接系统'],
level: -1
}
],
weather: [
{
expression: 'weather.temp < -1',
characters: ['天气有点冷~,多穿点衣服!', '天气凉,注意保暖哦', 'so cold ~~'],
level: 2
},
{
expression: 'weather.wind > 4',
characters: ['今天有大风哦,注意安全!'],
level: 1
},
{
expression: 'weather.weather == 0',
characters: ['今天有雨,别忘记带伞!', '今天可能会下雨哦~~'],
level: 3
},
{
expression: 'true',
characters: ['今天天气不错,哈哈', '风和日丽啊,祝你开心哦~'],
level: -1
}
],
festival: [
{
expression: 'date.m == 2 && $.date.d == 18',
characters: ['祝你生日快乐哦', '生日快乐,哈哈'],
level: 3
},
{
expression: 'date.m == 2 && $.date.d == 25',
characters: ['薇薇生日快乐哦!'],
level: 3
},
{
expression: 'festival.indexOf("元旦") >= 0',
characters: ['元旦快乐~~'],
level: 3
}
]
};摄像头人脸识别模块:
人脸识别模块主要代码使用python编写,主要硬件包括:摄像头X1,人体识别模块X1,红外传感器X1(莫名其妙烧坏了。。。。),系统在启动时会启动一个子进程,执行python脚本,并且会定时检验脚本的存活,如果python脚本推出,则会重启脚本,人脸识别使用face++提供的接口,首先根据人体识别模块与红外传感器判断是否有人,如果有人则进行拍照,然后进行人脸识别,如果在系统内置的集合中找到该人脸,则给系统推送一个消息,并将人名推送给前台显示页面进行问候语显示。当检测到人走之后,会显示其他问候语。
4.应用源代码:https://github.com/NinthCode/pandora.git
5.硬件连接图:
6.过程照片:
原子镜
未上镜子前
屏幕
7.作品照片:
8.作品视频:
http://player.youku.com/embed/XMzMwNDY3NDI4MA==
9.源代码压缩包:
**** Hidden Message ***** 666666666666 不错看看 基于树莓派的智能魔镜 学习一下 不错的作品!! 楼主6666 很不错的分享。。。。。。 学习,谢谢!!! 牛批哦,,,,,,,,,,,,,,,,,,,,,,,
页:
[1]
2