1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RaspberryPiとMESH(ボタンタグ+カスタムタグ)を使ったPCスクリーショット(Mac)の保存操作

Last updated at Posted at 2021-08-01

経緯

  • 趣味の自転車で使っている室内トレーニングアプリ(zwift,rouvyなど)でトレーニング中にスクリーンショットを保存したい
  • Macではスクリーショットはcommand+shift+3で保存できますが、トレーニング中に操作するのは危険なので、片手でも実行できるようにしたい

作ったもの

MESHのボタンタグを押すとMacのスクリーンショットを指定したフォルダに保存します。
IMG_9500_10.jpg IMG_8446_10.jpg

MESHを選択した理由

  • バッテリー内蔵で単体で動作し、自転車に取付け可能で片手で操作できること
  • SDK(JavaScript)があり、RaspberryPiと連携できること

構成

MESH

  • MESHハブアプリケーションでボタンタグをトリガーにHTTP GETを送るカスタムタグのレシピを作成します

カスタムタグとレシピはMESHハブアプリケーションを試してみるを参考にCode:Executeに下記コードを書いて作成します。

var apiURL = "http://ローカルホスト名:ポート番号/";
 
ajax ({
    url : apiURL,
    type : "get",
    timeout : 1000,
    success : function ( contents ) {
        log("HTTP receive.");
        callbackSuccess( {
            resultType : "continue"
        } );
    },
    error : function ( request, errorMessage ) {
        log("http request error occured");
        callbackSuccess( {
            resultType : "continue"
        } );
    }
});
 
return {
    resultType : "pause"
};

RaspberryPi

Raspberry Piに「MESH ハブ」アプリをインストールする方法を教えてほしいを参考にMESHハブで作成したレシピの実行環境をラズパイに構築し、HTTPリクエストを受けるローカルサーバー(Node.js + Express + child_process)を起動し、SSH接続(公開鍵認証)でAppleScriptをosascriptコマンドで実行します。

const express = require('express')
const app = express()
const {exec} = require('child_process')

//要ユーザ設定ファイル作成(~/.ssh/config) 
const sshcmd = "ssh [接続するsshのエイリアス名]"
//ファイル形式
const fileformat = "defaults write com.apple.screencapture type [ファイル形式]"
//画像ファイルの保存先パス
const savefilepath ="defaults write com.apple.screencapture location [画像ファイルの保存先パス] "
//AppleScriptのパス
const applescriptpath = "osascript [AppleScriptのパス] "
//AppleScript実行(ファイル形式と保存先指定)
//const cmd = sshcmd + fileformat + "&& " + sshcmd + savefilepath + "&& " + sshcmd + applescriptpath
//AppleScript実行
const cmd = sshcmd + applescriptpath

app.get('/', function (req, res) {
    exec(cmd, (error, stdout, stderr) => {
        if (error) {
            console.error(`exec error: ${error}`);
            return;
        }
        res.status(200)
        res.send('OK')
    })
})

app.listen(3000,() => console.log('Listening on port 3000'));

プログラムはサーバーが落ちても再起動するようにforeverコマンドを指定します。
【Node.js】 RaspberryPiのプログラムを自動起動・永続化・SSH ログアウト後もプロセスを残すを参考にサービス登録、再起動し、Foreverのプロセスを下記コマンドから確認します。

/etc/rc.local
sudo -u pi /usr/local/bin/node /usr/local/bin/forever start -a -d [動かしたいスクリプトのパス]
$ forever list
info:    Forever processes running
data:        uid  command             script                 forever pid  id logfile                    uptime       
data:    [0] EL4C /usr/local/bin/node [動かしたいスクリプトのパス]  1447    1705    /home/pi/.forever/EL4C.log 0:0:0:14.962

SSHはMacから公開鍵を取得し、ユーザ設定ファイル(~/.ssh/config)を作成します。

~/.ssh/config
Host [接続するsshのエイリアス名]
  HostName [ローカルホスト名]
  User [ユーザー名]
  IdentityFile [秘密鍵のパス]
  Port [ボート番号(デフォルトは22)]

Mac

  • スクリーショットを実行するAppleScriptをスクリプトエディタで作成します
AppleScript形式
on fullscreenshot()
	tell application "System Events"
                // Command+Shift+3を入力
		key code 20 using {command down, shift down}
	end tell
end fullscreenshot

fullscreenshot()
JavaScript形式
sys = Application("System Events");
// Command+Shift+3を入力
sys.keyCode("20", { using: ["command down", "shift down"]}); 

スクリプト保存時にファイルフォーマットを「スクリプト」に指定すると「.script」で保存されるため、これをosascriptコマンドで実行します。
なお、AppleScript形式の場合、ファイルフォーマットを「テキスト」に指定すると「.applescript」で保存されますが、それぞれosascriptで実行することが可能です。

最後に

このスクリプトを作成した後、Zwiftではショートカットキーの設定でF10キーでスクリーンショットを指定のフォルダに保存できることを知りました。
ただ、スクリーンショット操作は運動に集中しているとキーでもボタンでも押せないことや押し忘れることがあったため、自動で実行できるような仕組みがあると良いかと思いました。こちらは今後検討予定ですが、映像解析や他デバイスからのトリガーから実行できる仕組みを検討してみようと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?