2018年9月24日月曜日

Synology NAS上にGitサーバーを立ててVisual Studio 2017からpushする

半年くらい前にSynologyという会社のNASを買いました。

NASと言ったらBuffaloのイメージが強かったんですが、このSynology NASはもうほとんどただのLinuxパソコンのようで、Webからログインするとデスクトップのような画面が表示されて、そこでパソコンを操作するかのようにNASを管理することができます。また、いろいろなアプリケーションがパッケージセンターに公開されていて、それらをインストールすることで自分好みのNASにしていくことができます。例えばDropboxのように自分の各PC間でデータを同期させたり…。非常に強力なNASで、もはやただのNASというより「自前のクラウド」と言ったほうが良いような代物でした。

ですので、ただのNASとして使って、ひたすらファイルを詰め込むだけじゃなんかもったいないなと思い、Gitサーバーを立ててみることにしました。
自分でしか使わないのにわざわざGitサーバーを立てる意味とは…

準備

  • Visual Studio 2017をインストールした環境を2つ以上
  • 各PCにGitクライアントをインストール
  • Synology NASを使えるようにする

NASの準備

 まずはパッケージセンターからGitをインストールします。

次はSSHを有効にしておきます。コントロールパネルの「端末とSNMP」から有効にします。
この設定画面に書いてありますが、Synology NASはadministratorグループに属するアカウントでしかSSH接続できません。何このクソ仕様…。


そしたら次はGit用の共有フォルダを作りましょう。名前は何でもいいですが、今回はGitRemoteにしてみました。


続いてGitアクセス用のユーザーグループを作ります。コントロールパネル→グループで作成します。今回は「gitgroup」にしました。なんでもいいですが、小文字のほうがセンスがあります。
もちろんアクセス権限はGitRemoteフォルダのみに限定して、読み書き両方の権限を与えます。

つづいてユーザーを作ります。今回は「gituser」にしました。例によってなんでもいいですが、小文字のほうがセンスがあります。

グループはgitgroupのほか、administratorに所属させる必要があります。これは外部からSSH接続するためです。

administratorだとデフォルトですべてのフォルダにアクセスできてしまいますので、余計なフォルダへのアクセス権は消しておきましょう。
まあ、administratorなので自身のアクセス権の変更もできてしまうのですが…。


最後にGitを起動し、gituserにアクセス権を与えて準備完了です。

Gitリポジトリの作成

つづいてリポジトリを作成します。
SSHでNASに接続して操作をします。ターミナルはSSHがつながればなんでもいいですが、今回はPuTTYを使いました。

ログインしたら作成した共有フォルダ(/volume1/GitRemote)に移動し、リポジトリとなるフォルダを作ります。今回は「TestProject.git」としました。そして、
git --bare init --shared TestProject.git
を実行することで空のGitリポジトリを作成します。

このままでは全ユーザーにアクセス権が与えられてしまいますので、gitgroupに限定しましょう。
chown -R gituser:gitgroup TestProject.git/
chmod -R 770 TestProject.git/ 
これでグループ内にのみrwxのアクセスが与えられました。
 
これでGitリポジトリの作成は完了です。


Visual Studioでプロジェクトを作る

Visual Studioでプロジェクトを作ります。新しいプロジェクトを作る際に「新しいGitリポジトリの作成」にチェックを入れるのを忘れないようにしてください。

プロジェクトが出来上がったら、「チームエクスプローラー」→「設定」→リポジトリの設定」からリモートの「追加」ボタンを押します。
リモート名はorigin、フェッチ/プッシュはリポジトリのURLを指定します。今回は「ssh://gituser@[NASのIPアドレス]/volume1/GitRemote/TestProject.git」になります。

つづいて「チームエクスプローラー」→「同期」を開きます。
ここにある「プッシュ」ボタンを押せば、先ほど指定したリポジトリにプッシュを行います。

Gitのパスワード入力画面が開くので、ここでgituserのパスワードを指定します。

正常にプッシュされました。めでたしめでたし。

リポジトリからのクローン

別PCでリポジトリをクローンしてみます。
Visual Studioはクローンには対応していない(はず)なので、こればかりはコマンドラインから実行します。Visual StudioのプロジェクトのディレクトリからPowerShellを開き、
git clone ssh://gituser@[IPアドレス]/volume1/GitRemote/TestProject.git 
と入力すればリモートリポジトリからクローンします。
 
ちゃんとクローンされたプロジェクトが開けました。めでたしめでたし。

pushからの別PCからのpull

せっかく別PCでクローンしたので、こちらで編集してプッシュしてみます。
Hello, worldのコードを追加し、「チームエクスプローラー」→「変更」からローカルリポジトリにコミットします。
 
つづいて「チームエクスプローラー」→「同期」からプッシュします。

パスワードを入力したら無事プッシュされました。

元のPCに戻って、「チームエクスプローラー」→「同期」から今度は「プル」を選択します。

プルが完了したら見事にHello, worldのコードが出現しました。めでたしめでたし。

まとめ

これで無事NASにてGitサーバーを運用し、複数PCでプロジェクトを同期することができるようになりました。

Synology NASはadministratorグループに属していないとSSH接続ができないというちょっとアレな仕様があります。まあ、SSHでログインするなんてroot取って何かしらアレなことをしたい人くらいしかいないだろうという想定なんでしょうが、この仕様から、NASを利用する一般ユーザーにNAS上のリポジトリを触らせるのにはセキュリティ上の問題があります。これがどうにかならない限り、ソロGitからは抜け出せないでしょう。
えっ?ソロGitってpushする必要性あるの?????

あと、たぶんですけどVisual Studioは公開鍵認証をする方法が無さそうです。せっかくSSHならば公開鍵認証で認証を行って、毎回パスワードを入力しなくてもいいようにしたいんですけどねえ。

2018年9月2日日曜日

ダイキンのエアコンのリモコンを解析する

身の回りの家電には赤外線リモコンで操作するものがたくさんあります。エアコンもその一つです。それらのリモコンと同じ赤外線信号を送れるデバイスを作ることができれば、例えばネットワーク経由で本来リモコンが届かないようなところから家電を操作することができ、便利です。

というわけで、ダイキンのエアコンのリモコンを解析してみました。
解析したのは「ARC478A18」という型番のリモコンです。

幸運なことに、世の中のリモコンはだいたい940nmくらいの赤外線を使っており、だいたい38kHzで変調されています。なので、市販の赤外線受信モジュールで読めてしまうのです。
写真に写っているのはDSO touchというオシロスコープで、時間軸方向で8192サンプルのデータを取って保存することができるので、ロジアナとしても使うことができます。
これである程度のデータを集めることができて、物理層としてのフォーマットがわかれば、後はArduinoでもなんでも適当な受信ソフトを作り、リモコンで様々な操作を行って大量のデータを取ればどのようなコマンドを送っているかわかってくるはずです。

物理フォーマット 

ズバリ、物理フォーマットはこのようになっています。
データはいわゆる「家製協(AEHA)フォーマット」です。詳しくは以下のページが参考になります。
赤外線リモコンの通信フォーマット
このサイトにT=425μs (typ.)と書いてありますが、このリモコンもそれくらいでした。1回のリモコン操作で2つのフレームを送っており、第1フレームが20バイト、第2フレームが19バイトです。第1フレームと第2フレームの間には35.2msの間隔(トレーラー含む)が空いており、第1フレーム開始の30ms前からON/OFF=1T/1T('0'の信号)を5回(+トレーラー)送るようです。
この冒頭の点滅信号は何なのかよくわかりません。我が家のエアコンでは特にこの点滅を送らなくても(いきなり第1フレームを送出しても)ちゃんと受信してくれました。同期信号か何かなんですかね。

データ内容

続いて肝心のデータ内容です。かなりめんどくさいです。
それもそのはずです。エアコンにはいろいろな機能がありますが、1回の送信ですべての機能の設定内容を送っています。前回送信分との差分だけ(例えば『設定温度+1℃』のような内容のみ)の送信では、エアコンがリモコンの信号を受信できなかったときに、それ以降のリモコンの表示内容とエアコンの設定との整合性が崩れてしまうからです。

1フレーム目


2フレーム目


フレーム内容はこんな感じです。
AHEAフォーマットではデータは各バイトともLSB→MSBの順に送られている点に注意してください。補足欄に書いている数字はちゃんとMSBが左側になるように書いています。
最初の2バイトはカスタマーコード、3バイト目の下位4bitがカスタマーコード4bitずつをXOR取った値になっています。最後の1バイトはチェックサムで、それまでの送信データをすべて足し合わせた値になります。

なお、1フレーム目の「操作内容」は下表のとおりです。
操作内容
0x02 停止
0x03 設定温度変更
0x06 風向変更
0x07 風量変更
0x0C タイマー取消
0x0D 快適自動
0x0E 冷房
0x0F 除湿
0x10 暖房
0x16 風向左右変更
0x18 内部クリーン変更
0x1A 送風
0x1C ランドリー変更
0x1E 入タイマー変更
0x1F 切タイマー変更
0x2F おやすみ変更
0x34 風ないス変更
0x35 ストリーマ変更

何かボタンを押したときは、1フレーム目のText9にそのボタンに対応するこの値が入ります。

また、例えばランドリーモードは自動的に「風向上から2つ目」「切タイマー3時間」が入りますが、1frame目のText12の風向や2frame目のText11, 12の切タイマーはちゃんと風向上から2つ目、切タイマー3時間が入ります。

設定温度(2frame目Text6)はちょっとややこしいですが、絶対値の設定温度(冷房・暖房)の場合はそのままです。例えば25℃なら0b00110010(=50)です。設定温度は0.5℃単位で指定できますから、このように2倍の値を送っているのでしょうね。
相対値の設定温度(快適自動・除湿)の場合は下位5bitを使って設定します。上位3bitは0b110です。ですので、例えば+5℃設定なら0b11001010(下位5bitは0b01010=10)です。-5℃ならば0b11010110(下位5bitは10=0b01010の2の補数(反転させて1を足す)で0b10110)となります。

入タイマー/切タイマー時間は分単位で12bitで表されるので、例えば6時間だったら360分=0b000101101000になります。リモコンでは1時間単位でしか指定できませんが、ここに5分を指定したら本当に5分で止まるんでしょうかね。


それにしても、わざわざ2frameも送って設定をするのは何のためなんでしょうね。最初は昔の機器との互換性かと思っていましたが、大部分の設定内容が2frame目に入っている割には風向は1frame目にしか入っていませんし、すごく片手落ち感がありますよね。何に使っているかわからない(どんなボタンを押しても同じ1/0しか送信しない)ビットもたくさんありますし、1frameに圧縮して全データを送ることはできなかったんでしょうかね…。