Here are the pictures:
The frame
The frame mounted
The frame mounted with everything in it
Shot from the right
Shot from the left
Main Mirror
Other Mirror
Here are the pictures:
The frame
The frame mounted
The frame mounted with everything in it
Shot from the right
Shot from the left
Main Mirror
Other Mirror
Hi all,
Normally I don’t post a lot on forums…but I was so impressed by the Magic Mirror and thought I would share my (almost) final result so it can help others create their Magic Mirror.
I was looking for something completely different (how can I turn on the screen of my wall mounted Windows Tablets via Motion Detection) when I found the Magic Mirror and thought “WTF is this?! This is really cool! I need to get one now! Oh crap, it’s 2am…well let’s find out what I need and get everything tomorrow and build it!”.
This mirror is actually “version 2”, “version 1” was mounted in an Ikea poster frame and was not deep enough to mount everything in it, but I wanted to get some experience and still put the foil on it etc., the only thing was that 30min after hanging it on the wall, “version 1” came off the wall completely…fortunately the 23" screen was still fine, and because I was 100% sure I wanted to have this, I sat down and created a better one, one that actually stays on the wall! :)
Version 2 was actually really easy to built:
What parts did I need:
The only real issues I had setting everything up (which I’ve read, others also experienced this), were:
So…what modules do I use (on the latest Raspbian Jessie):
calendar_monthly
MagicMirror-QuoteCatalog
MMM-Carousel
MMM-cryptocurrency
MMM-domoticz
MMM-Globe
MMM-Hue
MMM-KeyBindings
MMM-MirrorMirrorOnTheWall
MMM-MovieListings
MMM-MyCommute
MMM-NetworkScanner
MMM-ping
MMM-rainfc
MMM-Scrobbler
MMM-soccer
MMM-syslog
MMM-WunderGround
worldclock
I have setup the MMM-MirrorMirrorOnTheWall Skill which works fine, but I am also running Domoticz to control and monitor basically everything in my house and I am using HA Bridge so Alexa can talk to Domoticz to execute scripts etc. So, I have created a little script so I can also say things like “Alexa, turn on main/other mirror” or “Alexa, turn on/off camera 1/2” (Alexa talks to HA Bridge, HA Bridge talks to Domoticz, Domoticz executes the script (in this case it SSH into the Mirror and execute the script below)):
#!/bin/sh
if [ $1 = "on1" ]
then
DISPLAY=:0.0 /usr/bin/chromium-browser --kiosk 'http://192.168.1.30:8081' &
elif [ $1 = "on2" ]
then
DISPLAY=:0.0 /usr/bin/chromium-browser --kiosk 'http://192.168.1.31:8081' &
elif [ $1 = "off" ]
then
DISPLAY=:0.0 xdotool key ALT+F4
elif [ $1 = "rotate" ]
then
DISPLAY=:0.0 xdotool key Right
elif [ $1 = "main" ]
then
DISPLAY=:0.0 xdotool key Home
else
echo "No option specified, Exiting..."
fi
exit
And here is a script I created to reinstall everything quickly for testing purposes:
#!/bin/sh
cd ~
bash -c "$(curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/master/installers/raspberry.sh)"
echo "Copying config files..."
cp ~/Documents/config.js ~/MagicMirror/config/
cp ~/Documents/custom.css ~/MagicMirror/css/
cd ~
echo "Installing Carousel and KeyBindings..."
cd ~/MagicMirror/modules/
git clone https://github.com/shbatm/MMM-Carousel.git
git clone https://github.com/shbatm/MMM-KeyBindings
cd ~/MagicMirror/modules/
echo "Installing My Commute and Soccer..."
git clone https://github.com/jclarke0000/MMM-MyCommute.git
cd MMM-MyCommute && npm install
cd ~/MagicMirror/modules/
git clone https://github.com/fewieden/MMM-soccer.git
cd MMM-soccer && npm install
echo "Installing WorldClock, Monthly Calendar and QuoteCatalog..."
cd ~/MagicMirror/modules/
git clone https://github.com/eouia/worldclock
git clone https://github.com/KirAsh4/calendar_monthly
git clone https://github.com/salpar/MagicMirror-QuoteCatalog.git
cd MagicMirror-QuoteCatalog && npm install
echo "Installing Domoticz, Globe and Hue..."
mkdir ~/MagicMirror/modules/MMM-domoticz
cd ~/MagicMirror/modules/MMM-domoticz
git clone https://github.com/M-Arvidsson/MMM-domoticz.git domoticz
cd ~/MagicMirror/modules/
git clone https://github.com/LukeSkywalker92/MMM-Globe.git
git clone https://github.com/MitchSS/MMM-Hue.git
echo "Installing CryptoCurrency and MovieListings..."
git clone https://github.com/matteodanelli/MMM-cryptocurrency.git
git clone https://github.com/Tueti/MMM-MovieListings.git
cd MMM-MovieListings && npm install
cd ~/MagicMirror/modules/
echo "Installing Wunderground, SysLog and RainForcast..."
git clone https://github.com/RedNax67/MMM-WunderGround.git
git clone https://github.com/paviro/MMM-syslog.git
git clone https://github.com/73cirdan/MMM-rainfc
echo "Installing SystemStatus and Network Scanner..."
git clone https://github.com/fewieden/MMM-ping.git
cd MMM-ping && npm install --productive
sudo chmod u+s /bin/ping
cd ~/MagicMirror/modules/
git clone https://github.com/ianperrin/MMM-NetworkScanner.git
cd MMM-NetworkScanner && npm install
echo "Installing Mirror Mirror On the Wall Skill..."
cp -R ~/MirrorMirrorOnTheWallSkill/MMM-MirrorMirrorOnTheWall/ ~/MagicMirror/modules/
cd ~
echo
echo "Now Reboot and everything should be working..."
echo
exit
I got my custom.css from here My First Magic Mirror, thanks @slametps .
And I made some small changes in the following files to get all the CSS working perfectly fine together:
I will post some pictures off my Magic Mirror in the 2nd post and I will post my full config.js file (without private info) in the 3rd post, otherwise this post will really be too long!
Okay, this is it! I think I now gave you guys enough info to build an exact replica :)
@MichMich Wat een geweldig project, thanks!
@raywo said in [MMM-NowPlayingOnSpotify] – Display the currently on Spotify playing song:
@marcnlx Awesome idea! Maybe you can add a screenshot.
Sure, here you go.
@yawns said in My Magic Mirror - 100x70cm:
I’m impressed. A nice and clean build, well written documentation, some nice pictures to look at and everything with markups and such. Very well done, this is how more Showrooms should look like :)
Thanks! If you know how many hours I spent “extra” on my laptop because of not so well written documentation, no markups and such…I thought I would save everybody some time ;)
Awesome module! I use it in fullscreen_below which creates a nice effect!
I did change the css a little (added margin-left and changed width to 90% for the album cover because this looks nicer with my custom.css), but this is really a great module.
@yawns You are correct. It’s mounted directly on top of the frame.
I didn’t notice heat is really a problem, except a little bit for the monitor board…although it now has way more room to let air out then when the back part of the monitor was still on it!
I was thinking about drilling some holes in the top of the frame to let the hot air out. There is also a small gap between the frame and the wall itself. On the RPi you can monitor temp as follows:
pi@mirror:~ $ vcgencmd measure_temp
temp=54.7'C
pi@mirror:~ $
I use a small script that shows temperature, but also shows it in Domoticz and sends a Telegram notification if the temperature gets too high:
pi@mirror:~ $ ./myscripts/rpitemp.sh
Raspberry Pi Temperature (domoticz) is 54.6 °C
pi@mirror:~ $ cat ./myscripts/rpitemp.sh
#!/bin/sh
domoticzip=192.168.1.12
user=xxxx
pass=xxxx
tempidx=204
maxtemp=70
RED='\033[0;31m'
NC='\033[0m'
val_temp=`vcgencmd measure_temp | cut -c 6-9`
val_temp2=`vcgencmd measure_temp | cut -c 6-9 | cut -c 1-2`
curl -s 'http://'$user':'$pass'@'$domoticzip'/json.htm?type=command¶m=udevice&idx='$tempidx'&nvalue=0&svalue='$val_temp'' > /dev/null
if [ $val_temp2 -gt $maxtemp ]; then
echo "${RED}Raspberry Pi Temperature ($(hostname)) is $val_temp °C ${NC}"
curl -s -X POST "https://api.telegram.org/botxxxxxxxxxxxxxxxxxxxxxxxxxxxx/sendMessage" -F chat_id=xxxxxxxx -F text="Raspberry Pi Temperature ($(hostname)) is $val_temp °C"
else
echo "Raspberry Pi Temperature ($(hostname)) is $val_temp °C"
fi
exit
pi@mirror:~ $
For some reason I can’t get it to work…
I copy & pasted the example from Github (corrected the Domiticz typo), changed the API details, but it doesn’t work. I suspect this other Domoticz module could have something to do with it…
{
module: 'MMM-domoticz/domoticz',
header: 'Smart Home',
position: 'bottom_left',
config: {
apiBase: "http://192.168.1.12",
apiPort: "80",
sensors: [
I changed renaming MMM-Domoticz (this module) to MMM-Domoticz2, but then it also would not run. Below is a copy of my config.js entry:
{
module: "MMM-Domoticz",
position: "bottom_left", // see mirror setting for options
config: {
updateInterval: 45, // every 45 seconds
apiBase: '192.168.1.12',
apiPort: 80,
apiUser: "abcd",
apiPw: "efgh",
moduleTitle: "Current temperatures Domiticz",
energyTitle: "Energy used by",
batteryTitle: "Battery level",
coTitle: "CO2 level"
energyNow: "Currently",
energyTotal: "Energy used",
batteryThreshold: 20,
coThreshold: 650,
showItems: ['temperature','energy','battery','co'], // possible items temperature, energy
excludedDevices: ['none'] // Device that will not be shown
}
},
@raywo said in [MMM-NowPlayingOnSpotify] – Display the currently on Spotify playing song:
@marcnlx Awesome idea! Maybe you can add a screenshot.
Sure, here you go.
Awesome module! I use it in fullscreen_below which creates a nice effect!
I did change the css a little (added margin-left and changed width to 90% for the album cover because this looks nicer with my custom.css), but this is really a great module.
I tested Kalliope yesterday night and once you know how it works, it’s pretty sweet! ;)
Unfortunately I noticed some bugs/issues which are discussed multiple times on Github, so for now I think I will wait until a later release since I need to restart Kalliope multiple times after 2-3 phrases because of pulseaudio issues which I can’t seem to fix:
2018-03-18 12:42:27 :: kalliope-0.5.1b :: File found in /home/pi/kalliope_starter_en/trigger/kalliope-EN-12samples.pmdl
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/trigger/snowboy/snowboydecoder.py", line 98, in __init__
stream_callback=audio_callback)
File "build/bdist.linux-armv7l/egg/pyaudio.py", line 750, in open
stream = Stream(self, *args, **kwargs)
File "build/bdist.linux-armv7l/egg/pyaudio.py", line 441, in __init__
self._stream = pa.open(**arguments)
IOError: [Errno -9985] Device unavailable
@sispheor said in Kalliope assistant + MM:
@marcnlx take a look to starter kits. It contains example. Also there is an example of usage of each neuron on the website.
Have fun !
I will! I’m going to check everything out later today, thanks!
@sispheor said in Kalliope assistant + MM:
@marcnlx @marcnlx you’ve set http://127.0.0.1:8080/kalliope for the neuron but the mirror up is 192.168.1.16. doesn’t it?
Also, notification and payload are not needed in the config of the module.
@sispheor 127.0.0.1 is the localhost IP, 192.168.1.16 is the external IP…the Magic Mirror is available on every IP in use on the RPi (listening address is set to 0.0.0.0).
I just commented out the notification and payload and thing are now showing on the Mirror! This is really cool! :)
Okay…now I need to figure out how to build the whole virtual assistant…on to “phase #2”.
In your demo video I saw a basically complete brain…is there any place where I can find that one? ;)
@sispheor said in Kalliope assistant + MM:
@marcnlx why are you trying to reach the URL from your browser? It’s an API. It should be accessed from a script only.
The CURL example gave me this output on the CLI. I was only using my browser to make sure I was able to reach the API.
Any idea what configuration mistake I could have made?
Hi,
I really love the Kalliope Virtual Assistant. I used the Manual Install (Method #2) option, since the one-liner command failed on my RPi.
I managed to install Kalliope (“Kalliope version”: “0.5.1b”), but I have some issues having all the messages show in MMM-Kalliope module (in upper_third) on the mirror.
I have added this to my ~/MagicMirror/config/config.js file:
{
module: "MMM-kalliope",
position: "upper_third",
config: {
max: "5",
keep_seconds: "8",
title: "Kalliope",
notification: "KALLIOPE",
payload: "my message"
}
}
I have added this to my ~/kalliope_starter_en/brain.yml file:
- name: "mm-say"
signals: []
neurons:
- magic_mirror:
mm_url: "http://127.0.0.1:8080/kalliope"
notification: "KALLIOPE"
payload: "{{ kalliope_memory['kalliope_last_tts_message'] }}"
- name: "mm-alert"
signals:
- order: "send an alert to magic mirror"
neurons:
- magic_mirror:
mm_url: "http://127.0.0.1:8080/kalliope"
notification: "SHOW_ALERT"
payload:
title: "my alert title"
message: "the message"
timer: 5000
And I have added this to the hooks in my ~/kalliope_starter_en/settings.yml file:
# on_start_speaking:
on_start_speaking: "mm-say"
I’m not sure what I am missing here…would anybody be able to help me out?
I also sometimes have an issue after Kalliope gets triggered by the WakeUp word related to the microphone/audio (but this might also be caused by the mic on the usb webcam I am using…):
what can i do for you?
Threshold set to: 4000
Say something!
Google Speech Recognition could not understand audio
I don't recognize that order
Waiting for trigger detection
yes sir?
Threshold set to: 4000
Say something!
Google Speech Recognition could not understand audio
I don't know this order
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/signals/order/order.py", line 84, in run
self.start_trigger()
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 382, in trigger
return self.machine._process(func)
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 1020, in _process
self._transition_queue[0]()
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 398, in _trigger
return self._process(event_data)
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 408, in _process
if trans.execute(event_data):
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 262, in execute
self._change_state(event_data)
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 273, in _change_state
event_data.machine.get_state(self.dest).enter(event_data)
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 119, in enter
event_data.machine.callback(handle, event_data)
File "/usr/local/lib/python2.7/dist-packages/transitions-0.6.4-py2.7.egg/transitions/core.py", line 990, in callback
func(*event_data.args, **event_data.kwargs)
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/signals/order/order.py", line 92, in start_trigger_process
self.trigger_instance = TriggerLauncher.get_trigger(settings=self.settings, callback=self.trigger_callback)
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/core/TriggerLauncher.py", line 32, in get_trigger
parameters=trigger.parameters)
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/core/Utils/Utils.py", line 140, in get_dynamic_class_instantiation
return klass(**parameters)
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/trigger/snowboy/snowboy.py", line 51, in __init__
sleep_time=0.03)
File "/usr/local/lib/python2.7/dist-packages/kalliope-0.5.1b0-py2.7.egg/kalliope/trigger/snowboy/snowboydecoder.py", line 98, in __init__
stream_callback=audio_callback)
File "build/bdist.linux-armv7l/egg/pyaudio.py", line 750, in open
stream = Stream(self, *args, **kwargs)
File "build/bdist.linux-armv7l/egg/pyaudio.py", line 441, in __init__
self._stream = pa.open(**arguments)
IOError: [Errno -9985] Device unavailable
When starting kalliope with the –debug option, I see lines like this in the debug log:
2018-03-17 13:55:30 :: kalliope-0.5.1b :: Magic_mirror call Magic Mirror MMM-kalliope-API: http://127.0.0.1:8080/kalliope
2018-03-17 13:55:31 :: kalliope-0.5.1b :: Magic_mirrorcannot get a valid json from returned content
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from {'notification': 'KALLIOPE', 'mm_url': 'http://127.0.0.1:8080/kalliope', 'is_api_call': True, 'payload': "{{kalliope_memory['kalliope_last_tts_message']}}", 'no_voice': False}, using {}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from KALLIOPE, using {'kalliope_memory': {'kalliope_last_tts_message': 'what can i do for you?'}}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from http://127.0.0.1:8080/kalliope, using {'kalliope_memory': {'kalliope_last_tts_message': 'what can i do for you?'}}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from True, using {'kalliope_memory': {'kalliope_last_tts_message': 'what can i do for you?'}}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from {{kalliope_memory['kalliope_last_tts_message']}}, using {'kalliope_memory': {'kalliope_last_tts_message': 'what can i do for you?'}}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronLauncher] replacing brackets from False, using {'kalliope_memory': {'kalliope_last_tts_message': 'what can i do for you?'}, 'name': 'sir'}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: Run neuron: "{'name': 'magic_mirror', 'parameters': {'notification': 'KALLIOPE', 'mm_url': 'http://127.0.0.1:8080/kalliope', 'is_api_call': True, 'payload': 'what can i do for you?', 'no_voice': False}}"
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [Utils]-> get_dynamic_class_instantiation : package path : kalliope.neurons.magic_mirror.magic_mirror
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [Utils]-> get_dynamic_class_instantiation : loading path : resources/neurons/magic_mirror/magic_mirror.py, as package Magic_mirror
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronModule] TTS args: {'name': 'pico2wave', 'parameters': {'cache': True, 'language': 'en-US'}}
2018-03-17 13:55:09 :: kalliope-0.5.1b :: Magic_mirror call Magic Mirror MMM-kalliope-API: http://127.0.0.1:8080/kalliope
2018-03-17 13:55:09 :: kalliope-0.5.1b :: Magic_mirrorcannot get a valid json from returned content
2018-03-17 13:55:09 :: kalliope-0.5.1b :: [NeuronModule] Say() called with message: {'content': '<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot POST /kalliope</pre>\n</body>\n</html>\n', 'status_code': 404, 'response_header': {'Content-Length': '148', 'X-XSS-Protection': '1; mode=block', 'X-Download-Options': 'noopen', 'X-Content-Type-Options': 'nosniff', 'Content-Type': 'text/html; charset=utf-8', 'Strict-Transport-Security': 'max-age=15552000; includeSubDomains', 'Connection': 'keep-alive', 'Content-Security-Policy': "default-src 'self'", 'Date': 'Sat, 17 Mar 2018 12:55:09 GMT', 'X-Frame-Options': 'SAMEORIGIN', 'X-DNS-Prefetch-Control': 'off'}}
Accessing the URL http://192.168.1.16:8080/kalliope, gives me this:
Cannot GET /kalliope
I also see the following error using the CURL example (removed the “<” from the beginning on the output of each line):
pi@mirror:~ $ curl -H "Content-Type: application/json" -X POST -d '{"notification":"KALLIOPE", "payload": "my message"}' http://127.0.0.1:8080/kalliope
!DOCTYPE html>
html lang="en">
head>
meta charset="utf-8">
title>Error</title>
/head>
body>
pre>Cannot POST /kalliope</pre>
/body>
/html>
pi@mirror:~ $
@bellroy said in My Magic Mirror - 100x70cm:
@marcnlx, well done and kudos to you on your magic mirror. I’m moving to a new place soon always have this thought that i want to build one of this bad boy as a home accessories. With you details guides of building the magic mirror is going to be very helpful and thanks for that.
you mind if i ping you separately if i hit the wall and hoping you can shed some lights.
No problem…just ping me if you hit any issues.