Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ MagicMirror

The super magic interface of my personal Magic Mirror. More information about this project can be found on my [blog](http://michaelteeuw.nl/tagged/magicmirror).

Modify js/config.js to change some general variables (language, wather location, compliments) and calendar.php to add your own ICS calendar
Runs as a php script on a web server with basically no external dependencies. Can use socket.io for XBEE integration, but isn't required for basic functionality.

Modify js/config.js to change some general variables (language, wather location, compliments, news feed RSS) and calendar.php to add your own ICS calendar
10 changes: 10 additions & 0 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ body, html {
margin-right: 10px;
}

.icon-small
{
position: relative;
display: inline-block;
font-size: 20px;
padding-left: 10px;
padding-right: -10px;
font-weight: 100;
}

.time .sec {
font-size: 25px;
color: #666;
Expand Down
6 changes: 6 additions & 0 deletions js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ var lang = window.navigator.language;
//var lang = 'en';

//change weather params here:
//units: metric or imperial
var weatherParams = {
'q':'Baarn,Netherlands',
'units':'metric',
'lang':lang
};

var feed = 'http://feeds.nos.nl/nosjournaal?format=rss';
//var feed = 'http://www.nu.nl/feeds/rss/achterklap.rss';
//var feed = 'http://www.nu.nl/feeds/rss/opmerkelijk.rss';
//var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml';

// compliments:
var compliments = [
'Hey, handsome!',
Expand Down
64 changes: 52 additions & 12 deletions js/ical_parser.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,27 @@ function ical_parser(feed_url, callback){
*/
this.makeDate = function(ical_date){
//break date apart
var dt = {
var dtutc = {
year: ical_date.substr(0,4),
month: ical_date.substr(4,2),
day: ical_date.substr(6,2),
hour: ical_date.substr(9,2),
minute: ical_date.substr(11,2)
}
//Create JS date (months start at 0 in JS - don't ask)
dt.date = new Date(dt.year, (dt.month-1), dt.day, dt.hour, dt.minute);
var utcdatems = Date.UTC(dtutc.year, (dtutc.month-1), dtutc.day, dtutc.hour, dtutc.minute);
var dt = {};
dt.date = new Date(utcdatems);

dt.year = dt.date.getFullYear();
dt.month = ('0' + (dt.date.getMonth()+1)).slice(-2);
dt.day = ('0' + dt.date.getDate()).slice(-2);
dt.hour = ('0' + dt.date.getHours()).slice(-2);
dt.minute = ('0' + dt.date.getMinutes()).slice(-2);

//Get the full name of the given day
dt.dayname =["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][dt.date.getDay()];
dt.monthname = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ][dt.date.getMonth()] ;

return dt;
}
Expand All @@ -66,7 +76,7 @@ function ical_parser(feed_url, callback){
this.events = [];

//Clean string and split the file so we can handle it (line by line)
cal_array = data.replace(new RegExp( "\\r", "g" ), "").split("\n");
cal_array = data.replace(new RegExp( "\\r", "g" ), "").replace(/\n /g,"").split("\n");

//Keep track of when we are activly parsing an event
var in_event = false;
Expand All @@ -80,18 +90,23 @@ function ical_parser(feed_url, callback){
cur_event = {};
}
//If we encounter end event, complete the object and add it to our events array then clear it for reuse.
if(in_event && ln == 'END:VEVENT'){
if(in_event && ln == 'END:VEVENT'){
in_event = false;
this.events.push(cur_event);
cur_event = null;
}
//If we are in an event
if(in_event){
else if(in_event){
//var lntrim = ln.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
//var lnsplit = lntrim.split(':');
//type = lnsplit[0];
//val = lnsplit[1];

//Split the item based on the first ":"
idx = ln.indexOf(':');
//Apply trimming to values to reduce risks of badly formatted ical files.
type = ln.substr(0,idx).replace(/^\s\s*/, '').replace(/\s\s*$/, '');//Trim
val = ln.substr(idx+1,ln.length-(idx+1)).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
val = ln.substr(idx+1).replace(/^\s\s*/, '').replace(/\s\s*$/, '');

//If the type is a start date, proccess it and store details
if(type =='DTSTART'){
Expand All @@ -101,9 +116,10 @@ function ical_parser(feed_url, callback){
cur_event.start_time = dt.hour+':'+dt.minute;
cur_event.start_date = dt.day+'/'+dt.month+'/'+dt.year;
cur_event.day = dt.dayname;
cur_event.start_date_long = dt.day+'. '+dt.monthname+' '+dt.year ;
}
//If the type is an end date, do the same as above
if(type =='DTEND'){
else if(type =='DTEND'){
dt = this.makeDate(val);
val = dt.date;
//These are helpful for display
Expand All @@ -112,8 +128,16 @@ function ical_parser(feed_url, callback){
cur_event.day = dt.dayname;
}
//Convert timestamp
if(type =='DTSTAMP') val = this.makeDate(val).date;

else if(type =='DTSTAMP'){
val = this.makeDate(val).date;
}
else {
val = val
.replace(/\\r\\n/g,'<br />')
.replace(/\\n/g,'<br />')
.replace(/\\,/g,',');
}

//Add the value to our event object.
cur_event[type] = val;
}
Expand Down Expand Up @@ -153,12 +177,28 @@ function ical_parser(feed_url, callback){
var future_events = [], current_date = new Date();

this.events.forEach(function(itm){
//If the event starts after the current time, add it to the array to return.
if(itm.DTSTART > current_date) future_events.push(itm);
//If the event ends after the current time, add it to the array to return.
if(itm.DTEND > current_date) future_events.push(itm);
});
return future_events;
}

/**
* getPastEvents
* return all events sheduled to take place before the current date.
*
* @return list of events objects
*/
this.getPastEvents = function(){
var past_events = [], current_date = new Date();

this.events.forEach(function(itm){
//If the event ended before the current time, add it to the array to return.
if(itm.DTEND <= current_date) past_events.push(itm);
});
return past_events.reverse();
}

/**
* load
* load a new ICAL file.
Expand All @@ -181,4 +221,4 @@ function ical_parser(feed_url, callback){
this.feed_url = feed_url;
//Load the file
this.load(this.feed_url);
}
}
28 changes: 25 additions & 3 deletions js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,26 @@ jQuery(document).ready(function($) {

(function updateWeatherForecast()
{
var iconTable = {
'01d':'wi-day-sunny',
'02d':'wi-day-cloudy',
'03d':'wi-cloudy',
'04d':'wi-cloudy-windy',
'09d':'wi-showers',
'10d':'wi-rain',
'11d':'wi-thunderstorm',
'13d':'wi-snow',
'50d':'wi-fog',
'01n':'wi-night-clear',
'02n':'wi-night-cloudy',
'03n':'wi-night-cloudy',
'04n':'wi-night-cloudy',
'09n':'wi-night-showers',
'10n':'wi-night-rain',
'11n':'wi-night-thunderstorm',
'13n':'wi-night-snow',
'50n':'wi-night-alt-cloudy-windy'
}
$.getJSON('http://api.openweathermap.org/data/2.5/forecast', weatherParams, function(json, textStatus) {

var forecastData = {};
Expand All @@ -260,10 +280,12 @@ jQuery(document).ready(function($) {
if (forecastData[dateKey] == undefined) {
forecastData[dateKey] = {
'timestamp':forecast.dt * 1000,
'icon':forecast.weather[0].icon,
'temp_min':forecast.main.temp,
'temp_max':forecast.main.temp
};
} else {
forecastData[dateKey]['icon'] = forecast.weather[0].icon;
forecastData[dateKey]['temp_min'] = (forecast.main.temp < forecastData[dateKey]['temp_min']) ? forecast.main.temp : forecastData[dateKey]['temp_min'];
forecastData[dateKey]['temp_max'] = (forecast.main.temp > forecastData[dateKey]['temp_max']) ? forecast.main.temp : forecastData[dateKey]['temp_max'];
}
Expand All @@ -275,10 +297,12 @@ jQuery(document).ready(function($) {
var opacity = 1;
for (var i in forecastData) {
var forecast = forecastData[i];
var iconClass = iconTable[forecast.icon];
var dt = new Date(forecast.timestamp);
var row = $('<tr />').css('opacity', opacity);

row.append($('<td/>').addClass('day').html(moment.weekdaysShort(dt.getDay())));
row.append($('<td/>').addClass('icon-small').addClass(iconClass));
row.append($('<td/>').addClass('temp-max').html(roundVal(forecast.temp_max)));
row.append($('<td/>').addClass('temp-min').html(roundVal(forecast.temp_min)));

Expand All @@ -297,9 +321,7 @@ jQuery(document).ready(function($) {

(function fetchNews() {
$.feedToJson({
feed:'http://feeds.nos.nl/nosjournaal?format=rss',
//feed:'http://www.nu.nl/feeds/rss/achterklap.rss',
//feed:'http://www.nu.nl/feeds/rss/opmerkelijk.rss',
feed: feed,
success: function(data){
news = [];
for (var i in data.item) {
Expand Down