NanoPi Neo で、作業場音楽環境をいろいろやらかしてみた

秋月で、なんとなく買ってしまった、nanopi。
あまらしとくのも難なので、作業場の音楽環境を、いろいろやらかすネタとして。
使ってみることに、しましたとさ。
![DSC_0385.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/837315ac-024e-fbfb-0764-922e34c42f9e.jpeg)

#導入前の環境
作業場には、パソコンとモニタ、デジタル入力のアンプと、あとAirmac Expressがあります。
Airmac Express経由で、サーバに入れてあるiTunesを流しています。
モニタはTV的なのを流用しているため、自動電源OFFが無く、パソコンとの電源連動がアレ。
アンプは中華製のやつで、入力切り替えがめんどくさく。
また、隣のまったり系のお部屋まで、デジタル分岐した光回線が伸びてます。
Airplay使わない時にAirmac Expressの電源落としたりしてるのですが、まあめんどくさく！。
Airplayのキックも、スマホのリモコンツール経由だったりしてね。
このへん、どうにかしていきたいな、と。

#ざっくり設計
適当に秋月を眺め、以下の方針でいくことに決定。
###オーディオ切り替え
・SPDIFベース、nanopiはSPDIF出力ありそうだしね
・同軸はめんどくさげなので、光入出力
・スイッチは１２５あたりで
・隣の部屋送りのため、２系統独立出力、切り替えで
・予備ふくめて、光２系統つけとくべ
###電源回り
・商用電源のスイッチは、SSRで
　・通常のリレー、入れるのに電流使うからね
・同じ筐体に一次側入れるのやなので、分離構造で
・途中配線はUSBだのEtherだのは避け、RJ11(モジュラー)で
###UI
　・一応ほら、音モノだし、LED+スイッチで
　・ノイズ的なアレ？
###I/F
　・どうみてもIO足りないので、まあI2Cで増やしますかね
　・リモコン使えるようにしたいかな
　・配線はパッチケーブルベースでいいべ、めんどいし
###おまけ要素
　・どうせだしPC用のUSB DACも入れちゃうべ

#詳細設計、電気編
・LEDは3mmをいくつか
・LEDの電流制限抵抗は、510Ω(緑黄赤)、270Ω(白青)
・パスコンは10uF
・SPDIF入力側の電源用Lは、47uH
・基板は秋月C基板で

・・・で、秋月発注、ざっくりしすぎてて、スイッチを買い忘れる失態ぶりでした。

#naniPiにAirplay喋らせる、基本動作編
まあ、ざっくりと。
![DSC_0384.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/b146391b-68d5-b9fc-b16d-9052ff468ad6.jpeg)

###OS
・ArmbianのUbuntuベース、5.35を使用
・最近のだと、SPDIF回りが、いろいろめんどいみたいです
・というか挫折しました
###SPDIF回り
・SPDIF認識のさせざまは、以下URLでなんとかなりました
　https://forum.armbian.com/topic/1891-spdif-output-on-nanopi-m1/
・SPDIFが正常に認識されると、以下な感じになりますです

```command
root@nanopineo:~# cat /proc/asound/cards
 0 [audiocodec     ]: audiocodec - audiocodec
                      audiocodec
 1 [sndhdmi        ]: sndhdmi - sndhdmi
                      sndhdmi
 2 [sndspdif       ]: sndspdif - sndspdif
                      sndspdif
```

###shairport
・perlが絡んでるので、改造とからくそーだし、あえての無印を使いました
・systemdに以下登録して、動かしてます

```shairport.service
[Unit]
Description = shairport

[Service]
ExecStart=/data/shairport/shairport.pl -a AirSelect --ao_devicename "default:CARD=sndspdif" --play_prog="/bin/touch /ramdisk/airplay_enable" --stop_prog="/bin/rm /ramdisk/airplay_enable"
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
```

　・ポイントは以下な感じ
　　・SPDIF出力は、「--ao_devicename "default:CARD=sndspdif"」でいける
　　・自動制御用に、airplay動いてるかをハンドリングしたかったんだけど
　　　ファイルの有無で判定することに
　　　キックは、オプションでいける親切設計でした
　　　「--play_prog="/bin/touch /ramdisk/airplay_enable"」
　　　「--stop_prog="/bin/rm /ramdisk/airplay_enable"」
　　　まあ、そゆことです


　・これでサービスを有効化しておくと、同じネットワーク上のiTunesに、以下のステキ表示が！
![Image2.png](https://qiita-image-store.s3.amazonaws.com/0/216885/e0c967ce-3f61-c65a-f519-42c0c4b0f0a0.png)
・あ、出ない時は、iTunesのホームシェアリング回りをぐぐってみて下さいな、確かアカウント登録とかいるはず
・shairportはまあ、Sync機能が無いので、それぞれの出力音が混ざる環境だと、エコー的になりますが、離れていれば大丈夫、ぶっちゃけKodiあたりと一緒です動作は

###SPDIF出力回り（電気要素）
・nanoPiは、１列ピンヘッダ側、I2Sの隣が、SPDIF出力です
・3.3VTTL出力っぽい、そのまま光なTOSLINK出力に突っ込めば、光デジタルとして使えますー

#SPDIF切り替え回り
###切り替えデバイス
・切り替えは、７４ロジックの３ステートバッファで、まあ「SN74HC125N」を使う感じ
　・選定ミスった！、126のほうがいいかもね
　・理由は、125はOEが反転動作なので、電源投入時には出力がぶつかっちゃう
・A入力にSPDIF入力を繋ぎ、OEをGPIOで制御、Y出力を４つぶつけて、「４入力１出力」にしました
・それを２回路で、４入力２出力ね
・パスコンは10uFを入れときましたとさ

###入出力
・SPDIF TTL入力２系統
・SPDIF 光入力２系統
・SPDIF 光出力２系統
　な、感じで

###基板
・さくっと、作りました、右側ね
![DSC_0387.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/ff1b4a9b-efed-f7de-88a8-0e703a11a9ba.jpeg)
・TOSLINKは東芝のが終売状態
・秋月の「ちっこいほう」のは、固定用の足が2.54mmピッチなので、かなり取り回しがラクですよん

#I2cエキスパンダー回り
###デバイス
・秋月に在庫がある、MicrochipのMCP23017を、２コ使用
・アドレスが3bitで選べるので、適当に設定
・データシート確認せずに基板を造るという、恐ろしい行為を行った為、無駄にプルアップ入れてしまった、、、あっはっは
・基板はこんなかんじー
![DSC_0386.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/b051071e-dba3-0ce5-017a-34185dc5ddc3.jpeg)
###製作留意点（電気要素）
・パスコンは10uF
・nanoPiは、I2cプルアップが入ってないので、この基板で（１ｋ）
・ロジック入力側は、1kのバッファ抵抗を
・ロジック出力側は、1kのプルアップ／ダウンを
・LED駆動は、電流制限として、270Ωと510Ω入れてます
・このIC、中身はマイコンらしく、起動に多少時間がかかります、数秒
・リセットピンは1kプルアップしてあげないと、動作不安定です
###nanoPi側からの認識
・ま、さくっと

```command
root@nanopineo:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- 22 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@nanopineo:~#
```

・どうして「２２」と「２３」なのか、よーわかってない適当さｗ
・まあ、てきとーに、アドレスピンをいじってます

#リモコン回り
###リモコンの選定
・まあ、Apple Remoteでいいかと
・中古を大人買いしたあと、自宅からも発掘されるというダメっぷりですが

###lirc設定
・まず、WiringNPをセットアップ
```command
git clone https://github.com/friendlyarm/WiringNP
cd WiringNP/
chmod 755 build
./build
```

・このままだと動かないので、WiringNPの以下を変更

```
$HOME/WiringNP/wiringPi/boardtype_friendlyelec.c
//allwinner h3
// kernel 3.x
の、該当部分以外をコメントアウト、該当部分を「-1(-1)」にする
参考：「/sys/class/sunxi_info/sys_info」の 「sunxi_board_id」
```

　このへんは、以下URLを参考にしました。
　http://nopnop2002.webcrow.jp/NanoPi-M1/NanoPi-M1-2.html

　これでリブートすると、sunxiのcirが生きてくるので、lircが使えるようになります。
　OrangePi用ですが、以下URLで！
　https://forum.armbian.com/topic/1953-configuring-orange-pi-pc-to-receive-irinfrared/

###Apple Remote回り
・Apple Remote、デバイスIDとかも送ってるみたいで、なかなかうまく学習してくれません
・以下URLから、設定貰ってきました
　http://lirc.sourceforge.net/remotes/apple/A1156

###リモコンによる、コマンドキック
・irexecを使います
・/etc/lirc/lircrc というファイルに、定義を書けばOKみたい

```lircrc
begin
        prog = irexec
        button = KEY_PLAY
        repeat = 2
        config = /data/airplay_control/control.pl playpause
        flags = quit
end
begin
        prog = irexec
        button = KEY_KPPLUS
        repeat = 2
        config = /data/airplay_control/control.pl volup
        flags = quit
end
begin
        prog = irexec
        button = KEY_FASTFORWARD
        repeat = 2
        config = /data/airplay_control/control.pl next
        flags = quit
end
begin
        prog = irexec
        button = KEY_REWIND
        repeat = 2
        config = /data/airplay_control/control.pl prev
        flags = quit
end
begin
        prog = irexec
        button = KEY_KPMINUS
        repeat = 2
        config = /data/airplay_control/control.pl voldown
        flags = quit
end
begin
        prog = irexec
        button = KEY_MENU
        repeat = 2
        config = /data/airplay_control/control.pl shuffle
        flags = quit
end
```

・で、systemdに登録、キック、テスト動作は単純に「irexec」を実行でOK

```irexec.service
[Unit]
Description = irexec

[Service]
ExecStart=/usr/bin/irexec
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
```

#aiplayによるiTunesのコントロール
・iTunesは、「DACP」という手順で、コントロールできます
　https://ja.wikipedia.org/wiki/Digital_Audio_Control_Protocol
・まあざっくり、httpで特定のポートにアクセス、リクエスト投げるだけ
・が、認証キーを一緒に送らないと、だめみたいです
・認証キーは、shairportに送られてるので、それ取り出します
・shairport.pl内の、「conn_handle_request」の中のやりとりで、サーバ応答があるので
・そこにトラップを仕掛けます、こんなかんじ

```perl:shairport.pl
sub conn_handle_request {
    my ($fh, $conn) = @_;

    my $req = $conn->{req};;
    my $clen = $req->header('content-length') // 0;
    if ($clen > 0 && !length($req->content)) {
        $conn->{req_need} = $clen;
        return; # need more!
    }

    my $resp = HTTP::Response->new(200);
    $resp->request($req);
    $resp->protocol($req->protocol);

#get Active-remote
    my $remoteid = $req->header('Active-Remote');
    if ($remoteid ne ""){
        open (OUTPUTREMOTE,">/ramdisk/airplay_activeremote");
        print OUTPUTREMOTE $remoteid;
        close (OUTPUTREMOTE);
    }
    $resp->header('CSeq', $req->header('CSeq'));
    $resp->header('Audio-Jack-Status', 'connected; type=analog');
```

・取り出したキーを使って、コントローラを適当に書いてみます

```perl:test.pl
#!/usr/bin/perl

use Socket;

 $activeremotefile = "/ramdisk/airplay_activeremote";
 open (FILE,$activeremotefile);
 ($activeremotekey) = (<FILE>);
 close (FILE);

 $command = $ARGV[0];
 $socket_port = 3689;
 $hostname = "192.168.0.221";

 $url = "/ctrl-int/1/" . $command;
 $addr = inet_aton("$hostname");
 socket(S, PF_INET, SOCK_STREAM, 0);
 my $socket_name = pack_sockaddr_in($socket_port, $addr);
 connect(S, $socket_name);
 binmode(S);
 select(S);
 $|=1;
 select(stdout);
 print S "GET ".$url." HTTP/1.0\r\nHost: $hostname\r\n";
 print S "Active-Remote: $activeremotekey\r\n\r\n";
 while (<S>) {
 print $_;
 }
 close (S);
```

・IPはiTunes動いてるPCのに書き換えてね、と
・コマンドは、以下資料が参考になるかと
　https://nto.github.io/AirPlay.html
・但し！、この資料古いらしく、使えないコマンドとか、ちらほらあります
・そこでiTunesを適当にハック、いまんとここんな感じみたい(iTunes12系列)

|コマンド|内容|
|:-----------------|:------------------|
|beginff|begin fast forward|
|beginrew|begin rewind|
|mutetoggle|toggle mute status|
|nextitem|play next item in playlist|
|previtem|play previous item in playlist|
|pause|pause playback|
|playpause|toggle between play and pause|
|play|start playback|
|stop|stop playback|
|playresume|play after fast forward or rewind|
|~~shuffle_songs~~|~~shuffle playlist~~|
|volumedown|turn audio volume down|
|volumeup|turn audio volume up|
prevgroup|前のグループへ|
nextgroup|次のグループへ|
restartitem|再生中のアイテムを、頭から|
increment|謎|
playspec|謎|
cue|謎だけどまあ、cue的な要素？|
repeatadv|リピート設定のトグル|
beginrew|restartitemと同一動作？|
nextcontainer|次コンテナ|
prevchapter|前チャプタ|
shuffletoggle|シャッフルのトグル|
prevcontainer|前コンテナ|
discrete-pause|謎|
nextchapter|次チャプタ|
controlpromptentry|謎|

・ちなみに、使えるコマンドは206が、無いコマンドは400が、dacp以外でパラメータとか渡さないとダメ系コマンドは501が帰ってくるみたいです
・先のリモコンと合わせて、無事リモコン操作ができるよーになりました、とさ

#箱の作成
・ま、アクリルで適当に
・一家に一台、レーザー加工機、べんりよー、30分作業だし！
![Image5.png](https://qiita-image-store.s3.amazonaws.com/0/216885/953df367-c582-750f-71bd-a7f61c5a7292.png)
![Image6.png](https://qiita-image-store.s3.amazonaws.com/0/216885/92a635c4-af9d-a96c-2f8a-2496aff20ee4.png)

#自動制御
・ま、やるきなく、スクリプトからコマンド呼び出しで、ごまかしてます
・自動切り替えとかべんりべんり

```perl:airselect.pl
#!/usr/bin/perl

use Time::HiRes;
$tempdir = "/ramdisk";

&i2cinit;

while(){
 &polling;
}
exit;

sub polling {

#detect
 my $statusrawdata = &i2cget("0x22","0x12");
 $statusrawdata = substr($statusrawdata,2,2);
 $statusrawdata = unpack("B8",  pack("H2", $statusrawdata ));

 my $detectbutton = &buttondetect($statusrawdata);
 my $detectpower = &powerdetect($statusrawdata);
 my $detectairplay = &loadstatus("airplay_enable");

#load autostatus
 my $autostatustime = &loadstatus("select_autostatustime","time");

#load status
 my $statuspower1 = &loadstatus("power1_status","data");
 my $statuspower2 = &loadstatus("power2_status","data");
 my $statusaudio1 = &loadstatus("audio1_status","data");
 my $statusaudio2 = &loadstatus("audio2_status","data");

#set default
 if ($statuspower1 eq "0"){$statuspower1 = "off";}
 if ($statuspower2 eq "0"){$statuspower2 = "off";}
 if ($statusaudio1 eq "0"){$statusaudio1 = "disable";}
 if ($statusaudio2 eq "0"){$statusaudio2 = "disable";}

#heartbeat
 my $statusheartbeat = &loadstatus("airswitch_heartbeat","data");
 my $statusheartbeattime = &loadstatus("airswitch_heartbeat","time");
 if ($statusheartbeat eq "0"){
   $statusheartbeattime = 100;
 }
 if ($statusheartbeattime > 10){
  if ($statusheartbeat eq "on"){
   $statusheartbeat = "off";
  }
  else {
   $statusheartbeat = "on";
  }
  &updatestatusdata("airswitch_heartbeat",$statusheartbeat);
 }

#autostatusupdate detect
 my $autostatusupdateflag = 0;
 if (($autostatustime > 7200)||($autostatustime == 0)){
  if ($detectbutton eq "off"){
   $autostatusupdateflag = 1;
  }
 }
#autostatusupdate exec
 if ($autostatusupdateflag == 1){
  &updatestatus("select_autostatustime","0");
  $statusaudio1 = "disable";
  $statusaudio2 = "disable";
  $statuspower1 = "off";
  $statuspower2 = "off";
  if ($detectpower eq "on"){
   $statusaudio1 = "spdif2";
   $statusaudio2 = "spdif2";
   $statuspower1 = "on";
   $statuspower2 = "on";
  }
  if ($detectairplay eq "1"){
   $statusaudio1 = "airplay";
   $statusaudio2 = "airplay";
   $statuspower2 = "on";
  }
 }

#manualstatusupdate exec
 else {
  if ($detectbutton eq "power1"){
   if    ($statuspower1 eq "on")      { $statuspower1 = "off";     }
   elsif ($statuspower1 eq "off")     { $statuspower1 = "on";      }
  }
  if ($detectbutton eq "power2"){
   if    ($statuspower2 eq "on")      { $statuspower2 = "off";     }
   elsif ($statuspower2 eq "off")     { $statuspower2 = "on";      }
  }
  if ($detectbutton eq "audio1"){
   if    ($statusaudio1 eq "disable") { $statusaudio1 = "airplay"; }
   elsif ($statusaudio1 eq "airplay") { $statusaudio1 = "pc";      }
   elsif ($statusaudio1 eq "pc")      { $statusaudio1 = "spdif1";  }
   elsif ($statusaudio1 eq "spdif1")  { $statusaudio1 = "spdif2";  }
   elsif ($statusaudio1 eq "spdif2")  { $statusaudio1 = "disable"; }
  }
  if ($detectbutton eq "audio2"){
   if    ($statusaudio2 eq "disable") { $statusaudio2 = "airplay"; }
   elsif ($statusaudio2 eq "airplay") { $statusaudio2 = "pc";      }
   elsif ($statusaudio2 eq "pc")      { $statusaudio2 = "spdif1";  }
   elsif ($statusaudio2 eq "spdif1")  { $statusaudio2 = "spdif2";  }
   elsif ($statusaudio2 eq "spdif2")  { $statusaudio2 = "disable"; }
  }
  if ($detectbutton ne "off"){
   &updatestatus("select_autostatustime","2");
  }
 }

#update status
 &updatestatusdata("power1_status",$statuspower1);
 &updatestatusdata("power2_status",$statuspower2);
 &updatestatusdata("audio1_status",$statusaudio1);
 &updatestatusdata("audio2_status",$statusaudio2);

#update led status

#  bit0 : O : POWER AUTO 1 (use power1 on/off)
#  bit1 : O : POWER ON 1 (use detect airplay)
#  bit2 : O : POWER AUTO 2 (use poser2 on/off)
#  bit3 : O : POWER ON 2 (use detect pc)
#  bit4 : O : POWER DETECT AIRPLAY (use automode)
#  bit5 : O : POWER DETECT PC (heartbeat)
#  bit6 : O : UNUSED
#  bit7 : O : UNUSED
#  bit8 : O : AUDIO TOSLINK1 1
#  bit9 : O : AUDIO AIRPLAY 1
#  bitA : O : AUDIO PCUSB 1
#  bitB : O : AUDIO TOSLINK2 1
#  bitC : O : AUDIO TOSLINK1 2
#  bitD : O : AUDIO TOSLINK2 2
#  bitE : O : AUDIO AIRPLAY 2
#  bitF : O : AUDIO PCUSB 2

 my (@ledarray);
 for (0..15){
  $ledarray[$_] = "0";
 }

 if ($statuspower1 eq "on")       {$ledarray[0]  = "1";}
 if ($detectairplay eq "1")       {$ledarray[1]  = "1";}
 if ($statuspower2 eq "on")       {$ledarray[2]  = "1";}
 if ($detectpower eq "on")         {$ledarray[3]  = "1";}
 if ($autostatusupdateflag eq "1"){$ledarray[4]  = "1";}
 if ($statusheartbeat eq "on")    {$ledarray[5]  = "1";}

 if ($statusaudio1 eq "spdif1")   {$ledarray[8]  = "1";}
 if ($statusaudio1 eq "airplay")  {$ledarray[9]  = "1";}
 if ($statusaudio1 eq "pc")       {$ledarray[10] = "1";}
 if ($statusaudio1 eq "spdif2")   {$ledarray[11] = "1";}
 if ($statusaudio2 eq "spdif1")   {$ledarray[12] = "1";}
 if ($statusaudio2 eq "spdif2")   {$ledarray[13] = "1";}
 if ($statusaudio2 eq "airplay")  {$ledarray[14] = "1";}
 if ($statusaudio2 eq "pc")       {$ledarray[15] = "1";}

 my $setstatus = unpack("H2", pack("B8","$ledarray[0]$ledarray[1]$ledarray[2]$ledarray[3]$ledarray[4]$ledarray[5]$ledarray[6]$ledarray[7]"));
 $setstatus = uc($setstatus);
 &i2cset("0x23","0x14","0x".$setstatus);
 $setstatus = unpack("H2", pack("B8","$ledarray[8]$ledarray[9]$ledarray[10]$ledarray[11]$ledarray[12]$ledarray[13]$ledarray[14]$ledarray[15]"));
 $setstatus = uc($setstatus);
 &i2cset("0x23","0x15","0x".$setstatus);

#update audioselector status
 my $setstatusaudio1 = "1111";
 my $setstatusaudio2 = "1111";

 if ($statusaudio1 eq "airplay")  {$setstatusaudio1 = "1101";}
 if ($statusaudio1 eq "pc")       {$setstatusaudio1 = "1110";}
 if ($statusaudio1 eq "spdif1")   {$setstatusaudio1 = "0111";}
 if ($statusaudio1 eq "spdif2")   {$setstatusaudio1 = "1011";}
 if ($statusaudio2 eq "airplay")  {$setstatusaudio2 = "1101";}
 if ($statusaudio2 eq "pc")       {$setstatusaudio2 = "1110";}
 if ($statusaudio2 eq "spdif1")   {$setstatusaudio2 = "0111";}
 if ($statusaudio2 eq "spdif2")   {$setstatusaudio2 = "1011";}
 if ($statusaudio1 eq "disable") {
  if ($detectairplay eq "0") {
   $setstatusaudio1 = "1101";
  }
 }
 if ($statusaudio2 eq "disable") {
  if ($detectairplay eq "0") {
   $setstatusaudio2 = "1101";
  }
 }
 $setstatus = unpack("H2", pack("B8","$setstatusaudio1$setstatusaudio2"));
 $setstatus = uc($setstatus);
 &i2cset("0x22","0x15","0x".$setstatus);

#update power status
 $setstatus = "0x00";
 if (($statuspower1 eq "on")&&($statuspower2 eq "on")){
  $setstatus = "0xC0";
 }
 elsif ($statuspower1 eq "on"){
  $setstatus = "0x80";
 }
 elsif ($statuspower2 eq "on"){
  $setstatus = "0x40";
 }
 &i2cset("0x22","0x14",$setstatus);
}

sub buttondetect {
 my $rawdata = $_[0];
 $rawdata = substr($rawdata,4,4);

 my $filename = $tempdir . "/button_used";
 if (-e $filename){
  if ($rawdata eq "0000"){
   unlink ($filename);
  }
  return ("off");
 }
 if ($rawdata ne "0000"){
  open (STATUSFILE,">$filename");
  print STATUSFILE ".";
  close (FILE);
 }

 if ($rawdata eq "0001"){ return ("power2");}
 if ($rawdata eq "0010"){ return ("power1");}
 if ($rawdata eq "0100"){ return ("audio2");}
 if ($rawdata eq "1000"){ return ("audio1");}
 return ("off");
}

sub powerdetect {
 my $rawdata = $_[0];
 $rawdata = substr($rawdata,2,1);

 if ($rawdata eq "1"){
  &updatestatus("power_detect",1);
  return ("on");
 }
 return ("off");
}

sub loadstatus {
 my $filename  = $tempdir . "/" . $_[0];
 if (-e $filename){
  if ($_[1] eq "data"){
   open (STATUSFILE,$filename);
   my ($filedata) = (<STATUSFILE>);
   close (FILE);
   return ($filedata);
  }
  if ($_[1] eq "time") {
   my $modtime = (stat($filename))[9];
   $modtime = abs ($modtime - time);
   return ($modtime);
  }
  return (1);
 }
 return (0);
}

sub updatestatus {
 my $filename  = $tempdir . "/" . $_[0];
 if ($_[1] eq "1"){
  if (!-e $filename){
   open (STATUSFILE,">$filename");
   print STATUSFILE ".";
   close (STATUSFILE);
  }
  return;
 }
 if ($_[1] eq "2"){
  open (STATUSFILE,">$filename");
  print STATUSFILE ".";
  close (STATUSFILE);
  return;
 }
 if ($_[1] eq "0"){
  if (-e $filename){
   unlink ($filename);
  }
  return;
 }
}

sub updatestatusdata {
 my $filename  = $tempdir . "/" . $_[0];
 my $prevstatus = &loadstatus($_[0],"data");
 if ($_[1] ne $prevstatus){
  open (STATUSFILE,">$filename");
  print STATUSFILE $_[1];
  close (STATUSFILE);
 }
}

sub i2cinit {
 &i2cset("0x22","0x00","0x2F");
 &i2cset("0x22","0x0c","0x00");

 &i2cset("0x22","0x01","0x00");
 &i2cset("0x22","0x0d","0x00");

 &i2cset("0x23","0x00","0x00");
 &i2cset("0x23","0x01","0x00");

 &i2cset("0x23","0x0c","0x00");
 &i2cset("0x23","0x0d","0x00");

 &i2cset("0x23","0x14","0xFF");
 &i2cset("0x23","0x15","0xFF");

 &i2cset("0x22","0x14","0x00");
 &i2cset("0x22","0x15","0xFF");

# sleep (3);

 &i2cset("0x23","0x14","0x00");
 &i2cset("0x23","0x15","0x00");
}

sub i2cset {
 my $i2caddress = $_[0];
 my $memaddress = $_[1];
 my $memsetdata = $_[2];

 my $systemcommand = "/usr/sbin/i2cset -y 0 " . $i2caddress . " " . $memaddress . " " .$memsetdata;
 system ($systemcommand);
 Time::HiRes::sleep(0.2);
}

sub i2cget {
 my $i2caddress = $_[0];
 my $memaddress = $_[1];
 my $systemcommand = "/usr/sbin/i2cget -y 0 " . $i2caddress . " " . $memaddress;
 my $result = `$systemcommand`;
 Time::HiRes::sleep(0.2);
 return ($result);
}
```

・で、systemdに登録して、完了

#配線とか
・検討中
![DSC_0389.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/9722011c-54bb-8462-fb05-3f94af5bf9e4.jpeg)

・ごちゃってます
![DSC_0395.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/b0b918fb-1993-fb46-84c6-2a39fcd38a9d.jpeg)

・LEDは、いいかんじ
![DSC_0394.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/255f569e-7d83-12db-9dbe-958ca7c68f0e.jpeg)

#ま、完成
・べんりべんり
![DSC_0425.jpg](https://qiita-image-store.s3.amazonaws.com/0/216885/56fe9e88-c975-f10d-82c8-868be4633856.jpeg)