([2022/1/3更新]MagicMirror 2.18.0にあわせて更新しました。)
はじめに
RaspberryPiでフォトフレームを作るのはよくあるネタですが、えいっとPythonでコード書いて作っても、しばらくすると写真を選ぶのメンドクサイとか、ついでに天気予報を横に出したいとか、日常で使い出すことを考えると、コードメンテがタイヘンになってきます。
そこでオープンソースのMagicMirror2を使って、簡単に(設定は1つの設定ファイルと1つのcssファイルだけ、そして若干のコマンド入力だけです)、そしてメンテも最小(ssh経由でモジュールのアップデートと設定修正くらい)、普通に日常で使えそうなフォトフレームを作ってみました。
RaspberryPiを買ったけど机の中に入れっぱなしになっている、なんとなく高性能なフォトフレームをさりげなく家のリビングに置いて家族に自慢したい、実家に置いて子供の成長を見せたい、なーんてお父さんにオススメです。
※補足:既存のオープンソースMagicMirror2を使うだけなのでカンタンですが、タダでさえ説明が長いのに、もっと長くなると読むのがめんどくさくなりますので、RaspberryPiでなんとなく遊んでみて、SSH経由でコマンドがある程度入力できる方を対象にしています。
MagicMirror2を設定する
MagicMirror2は、今ハヤりのElectronを使い、表示画面をhtmlで生成してChromiumで表示する仕組みです。画面構成をcssでカスタマイズできるので楽ちんです。
MagicMirror2は、もともと鏡の裏に液晶ディスプレイを仕込んでおいて、鏡を見ながら今日の予定を確認したり、天気や交通情報を表示したりする、未来っぽい仕組みを作る仕組み、だそうです。構築環境やモジュールが揃っており、組み合わせれば超簡単に便利なフォトフレームになります。
ここでは、以下機能を設定してみます。
- Google Photoの指定したアルバムを表示する。
- Google Photoのアルバム機能は地味に便利で、普通に好きな写真を選んでアルバムを作ってもいいのですが、特定の人物が写っている・特定の地域などをフィルタ設定して、勝手にアルバムを作成する機能があります。これで、例えば家の子供を設定すると、写真を選ばずに、子供だけ出てくるステキなフォトフレームができあがります。
- 時計を表示してGoogleカレンダーと連携する。
- Googleカレンダーから直近の予定を出せば、便利かもしれません。
- 天気予報を表示する。
- ベタですがいつも表示されており、すぐに確認できるといいですよね。
- 近くに誰かいるときだけ画面が表示される。
- PIRセンサ(人感センサー)をつないで、近くに誰かいるときのみ、画面表示します。ずっと画面が表示されっぱなしになるのを防ぎます。
出来上がるとこんな感じに表示されるフォトフレームが完成します。(画面をデジカメで撮影したので見にくいですが…)
必要な環境
- Raspberry Pi(2以上)
- ゼイタクにElectronで動いているので、Raspberry Pi2以上でないと動かないようです。ネットワークに接続するので、無線LANのある3以上のほうが楽でしょう。
- SDカードは、それほど容量はいらないので、8GB以上で十分かと思います。
- HDMI接続の液晶ディスプレイ
- この記事では、解像度800x480のHDMIディスプレイを使っていますので、解像度が異なる場合はテキトウに修正してください。
- SPI接続などHDMI以外の液晶ディスプレイだと、画面描画が遅いので不向きです。
- PIRセンサーを使って、近くに誰かいるときのみ画面表示する場合は、HDMI出力のON/OFFかHDMI CMCでディスプレイに表示状態を伝えますので、これに対応したHDMIモニタが便利です。(リレーを付けて直接ディスプレイの電源を制御する方法もあります)
- このページの最後に、その昔ドコモがばらまいていたフォトフレームの液晶をHDMIディスプレイにするビンボウネタも載せましたので、ご参照ください。
- PIRセンサー(人感センサー)(必要であれば)
- 人が近くにいるとONになるセンサーです。「HC-SR501」と呼ばれるPIRセンサーユニットは、RaspberryPiに直接接続できるので便利です。秋月電子で400円で売っています。AmazonやAliexpressでも同様の部品が売っているので、テキトウに選んでください。
- SSHでログインしたりファイルを修正したりするPC
- Raspberry Piにキーボードを繋いでもいいのですが、実際にフォトフレームとしてリビングなどに置き始めると、とてもめんどくなりますので、PCにSSHでコンソールとファイル転送できる環境があると楽です。自分は、コンソールにWindows Terminal、ファイル転送にWinSCPを使っています。
APIキーを取得する
- 天気予報はOpenWeatherを使うので、無償のAPIキーを取得しておきます。
- Google Photoをアクセスするためには、Google Photos Library APIのクライアントキーを取得する必要があります。利用するMMM-GooglePhotosモジュールの「Get token.json」の説明を見て、
client_secret_xxxx...xxx.json
ファイルを取得してcredentials.json
にリネームしておきます。
MagicMirror2のインストール
- Xを使うので、Raspberry Pi OS(Raspbian) のDesktop版をインストールしてください。
sudo raspi-config
などでネットワークやSSHを有効の設定を行い、普通に使える状態にします。今後は、最初から設定されている pi ユーザを使って作業を行います。 - MagicMirror2のインストールは、ドキュメントのAutomatic Installation Scripts項目に書いてある、MagicMirror_scriptsが簡単です。具体的には、piユーザでログインしたら、そのまま以下スクリプトを実行します。
bash -c "$(curl -sL https://raw.githubusercontent.com/sdetweil/MagicMirror_scripts/master/raspberry.sh)"
- これで、電源を入れれば勝手にMagicMirror2が起動します。
MagicMirror2の標準モジュールを設定する
設定ファイルは、/home/pi/MagicMirror/config/config.js
だけです。存在しなければ、cp /home/pi/MagicMirror/config/config.js.sample /home/pi/MagicMirror/config/config.js
でサンプルファイルをコピーして使います。
MagicMirror2はこの設定ファイルを監視しており、更新するとMagicMirror2を再起動して反映しますので、ファイル転送ソフトで手元のPCから修正すると楽です。
設定ファイルはjavascriptでconfig配列変数を設定しているだけですので、カッコやカンマなど記述に注意しながら修正します。
MagicMirror2は、モジュールを追加することで、いろいろな情報を画面に表示することができます。まずは標準モジュール設定を設定して、天気予報と予定を表示しましょう。詳しくは、MagicMirror2 Documentationを参照してください。
- 表示を日本語に ([2021/7/13更新]2.16.0に合わせました。)
language: "ja",
locale: "ja_JP.UTF-8",
- ログを残さないように (2021/4/12に追加しました)
- 未記入だと
logLevel: ["INFO", "LOG", "WARN", "ERROR"],
になるようです。ログは~/.pm2/logs/
に残ります。このまま運用すると、ログが溜まってしまいますので、完成したらこの設定に変更しましょう。(SDカードへの書き込みを抑えられます。)
- 未記入だと
logLevel: [],
- complimentsモジュールを非表示にします。
{
module: "compliments",
disabled: true,
position: "lower_third"
},
- 標準の天気予報モジュール「weather」を設定します。
"YOUR_OPENWEATHER_API_KEY"
の部分に、先程取得したOpenWeatherのAPIキーを取得します。locationIDに、表示したい場所のIDを記載します。(調べ方はconfig.js.sampleに書いてあります)- ([2021/7/13更新]標準の天気予報モジュール変更(weather)に伴い修正しました。)
{
module: "weather",
position: "top_right",
config: {
weatherProvider: "openweathermap",
type: "current",
location: "Fuji-kawaguchiko",
locationID: "7281819",
updateInterval: 1200000 ,
apiKey: "YOUR_OPENWEATHER_API_KEY"
}
},
{
module: "weather",
position: "top_right",
header: "Weather Forecast",
config: {
weatherProvider: "openweathermap",
type: "forecast",
location: "Fuji-kawaguchiko",
locationID: "7281819",
updateInterval: 1200000 ,
apiKey: "YOUR_OPENWEATHER_API_KEY"
}
},
- 標準モジュールの「calendar」で、iCal形式の予定を表示できます。例えばGoogleカレンダーの予定を表示したい場合は、Googleカレンダー設定画面の「マイカレンダーの設定」にある「iCal形式の非公開URL」を使います。例えば以下のように修正します。
{
module: "calendar",
header: "予定",
position: "top_left",
config: {
colored: true,
coloredSymbolOnly: true,
// Interval 120min
fetchInterval: 7200000,
dateFormat: "YYYY MM DD" ,
fade: false,
timeFormat: "absolute" , //absolute or relative or dateheaders
calendars: [
{
color: "#4169e1",
symbol: "user",
url: "ここにGoogleカレンダーのiCal形式の非公開URLを挿入します"
}
]
}
},
GooglePhotoの写真を表示するモジュールをインストールする
MagicMirror2は、モジュールを追加することで、いろいろな情報を画面に表示することができます。まずは、Google Photoの写真を背景に表示するMMM-GooglePhotosモジュールを入れてみましょう。
他のモジュールも、基本的には同じ方法でインストールできます(詳細は各モジュールのドキュメントを参照してください)。piユーザでログインして、以下コマンドを入力します。
cd ~/MagicMirror/modules/ #←モジュールを入れるディレクトリに移動
git clone https://github.com/eouia/MMM-GooglePhotos.git #←モジュールのURL+.gitでgithubから取得
cd MMM-GooglePhotos #←取得したモジュールのディレクトリに移動
npm install #←インストール
- Google Photos Library APIのクライアントキーをコピーします。「APIキーを取得する」項目で取得した
credentials.json
を/home/pi/MagicMirror/modules/MMM-GooglePhotos/
にコピーして、以下コマンドを実行します。
cd ~/MagicMirror/modules/MMM-GooglePhotos
node generate_token.js
- 設定ファイルを修正します。先程の天気予報モジュールと同じような体裁で、設定ファイル
/home/pi/MagicMirror/config/config.js
のmodules: [ … ]
の中に以下を挿入します。
{
module: "MMM-GooglePhotos",
position: "fullscreen_below",
config: {
// Set your album name.
//like ["My wedding", "family share", "Travle to Paris"]
albums: ["表示したいアルバムの名前"],
// Interval 90 seconds.
updateInterval: 90 * 1000,
sort: "random", // "new", "old", "random"
uploadAlbum: null, // Only album created by `create_uploadable_album.js`.
condition: {
fromDate: null, // Or "2018-03", RFC ... format available
toDate: null, // Or "2019-12-25",
minWidth: null, // Or 400
maxWidth: null, // Or 8000
minHeight: null, // Or 400
maxHeight: null, // Or 8000
minWHRatio: null,
maxWHRatio: null,
// WHRatio = Width/Height ratio ( ==1 : Squared Photo, < 1 : Portraited Photo, > 1 : Landscaped Photo)
},
// These values will be used for quality of downloaded photos to show. real size to show in your MagicMirror region is recommended.
showWidth: 800,
showHeight: 480,
//timeFormat: "YYYY/MM/DD HH:mm", // Or `relative` can be used.
timeFormat: "YYYY/MM/DD",
autoInfoPosition: false,
}
},
- showWidthとshowHeightは、接続するディスプレイの解像度を設定します。
- Google Photoのアルバム名は、日本語も使えますが、UTF-8で記載しているか確認しましょう。アルバムを複数記入すると、順に表示されます。細かい設定は、MMM-GooglePhotosモジュールの説明を参照してください。
- Google Photoのアルバムにそれなりの数の写真が保存されていると(数千枚以上)、写真を表示しなくなります…。アルバムは最大で数百枚程度にしましょう。
- アルバムの写真登録数に比例して、最初の写真が表示されるまでに時間がかかります。試しに数枚程度のアルバムを作成して、動作確認しましょう。
PIRセンサーで画面を節電するモジュールをインストールする
PIRセンサー(HC-SR501)を使って、誰かいるときだけ画面が表示されるように設定します。センサは、例えば以下のように接続します。
HC-SR501側 | RaspberryPi側 |
---|---|
VCC | 2 (5V) |
Out | 15 (GPIO22) |
GND | 6 (GND) |
- モジュールのインストール モジュールは、MMM-PIR-Sensor を使います。モジュールのインストールは、piユーザでログインして、以下コマンドを入力します。
cd ~/MagicMirror/modules/
git clone https://github.com/paviro/MMM-PIR-Sensor.git
cd MMM-PIR-Sensor
npm install
- ([2022/1/3更新]npm install でエラーが発生する場合は、「モジュールをアップデートする」項目を参照してください。)
- GPIOの使用、HDMI制御を行うため、以下権限を追加します。
sudo usermod -a -G gpio pi
sudo chmod u+s /opt/vc/bin/tvservice && sudo chmod u+s /bin/chvt
- 設定ファイル
/home/pi/MagicMirror/config/config.js
のmodules: [ … ]
の中に以下を挿入します。MMM-PIR-Sensor のExampleほぼそのままです。
{
module: 'MMM-PIR-Sensor',
// Remove this line to avoid having an visible indicator
position: "bottom_left",
config: {
// Turn HDMI OFF after 60 seconds of no motion,
// until motion is detected again
powerSavingDelay: 60,
// Customizing the indicator
presenceIndicator: "fa-eye",
presenceOffIndicator: "fa-eye",
presenceIndicatorColor: "#f51d16",
presenceOffIndicatorColor: "#2b271c"
}
},
- 設定について
- 自分が使用したHDMIディスプレイは、無信号状態でディスプレイが節電状態になりましたので、
supportCEC
は設定せずにデフォルトで使用しています。CECが使えそうならば、MMM-PIR-Sensor のExampleをマネしてsupportCEC: true,
を追加するといいでしょう。 -
powerSavingDelay
は、センサが未感知状態になった後、設定した秒数が経過した後にディスプレイをOFFにします。 -
presenceIndicator
/presenceOffIndicator
を設定すると、position
で指定した位置(上記だと左下)に目の形をしたアイコンが出てきます。センサがONになると赤色、OFFになると黒色になるので、これでセンサの状態を確認できます。 - リレーを接続してディスプレイの電源をON/OFFする場合、
relayPin
、relayState
を設定します。
- 自分が使用したHDMIディスプレイは、無信号状態でディスプレイが節電状態になりましたので、
画面デザインをカスタマイズする
/home/pi/MagicMirror/css/custom.css
を新規作成し、そこにスタイルシートを記載すると、設定を上書きすることができます。/home/pi/MagicMirror/css/main.css
やモジュール内のcssファイルを修正すると、バージョンアップ時に上書きされてしまいますので、元のcssファイルを見ながら、修正したい項目をcustom.cssにコピーして修正します。
いくつか自分が追加した例を載せますので、custom.cssに追加してみてください。
- 画面いっぱいに表示する。(ディスプレイが低解像度の場合オススメです。)
body {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.region.fullscreen {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
pointer-events: none;
}
.region.fullscreen.below {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
- ぼかした背景を表示しない。(MMM-GooglePhotosモジュールのTipに載っています。)
#GPHOTO_BACK {
display:none;
}
- GooglePhotoの写真を画面いっぱいに表示する。(画面と縦横比が異なる場合は、切り取って表示します。切り取りたくない場合は、
background-size:auto;
に変更します(画面と縦横比が異なる場合、黒い未表示部分ができます))。
#GPHOTO_CURRENT {
background-size:cover;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom:0px;
}
- 時計や天気予報の文字を黒色で縁取りして、写真と重なった文字を見やすくします。
- ([2021/7/13更新]標準の天気予報モジュール変更(weather)に伴い修正しました。)
.clock {
text-shadow:
1px 1px 2px black , -1px 1px 2px black ,
1px -1px 2px black , -1px -1px 2px black ;
}
.weather {
text-shadow:
1px 1px 2px black , -1px 1px 2px black ,
1px -1px 2px black , -1px -1px 2px black ;
}
.calendar {
text-shadow:
1px 1px 2px black , -1px 1px 2px black ,
1px -1px 2px black , -1px -1px 2px black ;
font-weight: 700;
}
表示フォントを変更する
デフォルトのフォントデザインは簡体字に寄っていて読みにくいので、フォントをインストールして変更します。個人的に好きなMigMix 1Pに変えてみます。
- フォントのインストール
sudo apt-get install fonts-migmix
-
/home/pi/MagicMirror/css/custom.css
に追加します。
body {
font-family: "MigMix 1P", "Roboto Condensed", sans-serif;
}
.light {
font-family: "MigMix 1P", "Roboto Condensed", sans-serif;
font-weight: 300;
}
.regular {
font-family: "MigMix 1P", "Roboto Condensed", sans-serif;
font-weight: 400;
}
.bold {
font-family: "MigMix 1P", "Roboto Condensed", sans-serif;
font-weight: 700;
}
アップデートする
時々画面上部に「アップデートしたよ」(実際には英語です)と出たら、アップデートしましょう。
以下アップデートを実行するときは、pm2 stop all
コマンドを入力して、MagicMirrorを停止しておきます。(停止しておかないと、アップデートに失敗します…)
-
MagicMirror2をアップデートする。
- インストールで使ったMagicMirror_scriptsのアップデートスクリプトを使うのが簡単です。具体的には、piユーザでログインしたら、そのまま以下スクリプトを実行します。
bash -c "$(curl -sL https://raw.githubusercontent.com/sdetweil/MagicMirror_scripts/master/upgrade-script.sh)" apply
- モジュールをアップデートする。
- piユーザでログインしたら、以下スクリプトを実行します。「モジュール名」の部分に、アップデートしたいモジュール名を入れます。
cd ~/MagicMirror/modules/「モジュール名」
git pull
npm install
- npmをアップデートする。
New patch version of npm available! 6.14.5 → 6.14.7
Changelog: https://github.com/npm/cli/releases/tag/v6.14.7
Run npm install -g npm to update!
モジュールをアップデート後などで、上記のようなメッセージが出てきた場合は、以下のようにrootでアップデートします。
sudo npm install -g npm
MagicMirror v2.18以降で、モジュールインストール・アップデート時にエラーが出る場合[2022/1/3追加]
MagicMirror v2.18以降、モジュールを npm install した時、以下のようなエラーが出ることがあります。具体的には、古いモジュールである MMM-PIR-Sensor で発生します。
An unhandled error occurred inside electron-rebuild
Could not detect abi for version 16.0.5 and runtime electron. Updating "node-abi" might help solve this issue if it is a new release of electron
Error: Could not detect abi for version 16.0.5 and runtime electron. Updating "node-abi" might help solve this issue if it is a new release of electron
MagicMirror2のフォーラムにとりあえず動かす方法が乗っていました。
- MagicMirrorを停止し、MMM-PIR-Sensorのpackage.jsonを手作業で修正します。
pm2 stop all
cd ~/MagicMirror/modules/MMM-PIR-Sensor/
vi package.json
- dependencies 項目を探し、以下1行を追記します。
"dependencies": {
"onoff": "latest",
"magicmirror-rebuild": "^1.0.0", #←この行を追加します。
"electron-rebuild": "^1.2.1"
}
- モジュールを再構築します。
npm install
Magicmirror2 を停止・再起動する
Magicmirror2は、PM2を使ってプロセスを管理しています。モジュールのアップデートなどでMagicmirror2を再起動したい場合は、以下コマンドを入力します。
- Magicmirror2を再起動
pm2 restart all
- Magicmirror2を停止
pm2 stop all
- Magicmirror2を起動
pm2 start all
おまけ。Docomoフォトフレーム02の液晶を再利用する。
数年前、Docomoのケータイやスマホを契約しようとすると、なぜかDocomoフォトフレーム02を契約料だけで持っていってくれ、という謎の勧誘を受けてしまい、1台持って帰って押し入れに入れっぱなしにしておりました。これを今回のディスプレイに再利用しました。
このDocomoフォトフレーム02は、9インチ800x480の解像度を持つ「AT090TN12」が入っています。恐ろしいことにAliexpressには、この液晶をHDMI接続するためのボードが売っています。これを買って、液晶を取り出して接続すると、お安くフォトフレームが完成します。