スープカレー作った
お料理ブログ書きたいなぁと思ってたけど、
スマホアプリから写真貼ればラクやん?と気づいたので、雑に書いてみる。
アプリから写真あげて、PCで編集してるけど、なぜかmarkdown編集できなくてつらい。
(スマホアプリの設定で、編集モードをmarkdownにしておけば問題なかったらしい)
最近過食気味だったので、糖質少なめな具だくさんスープを作って生きております。
トマトスープが作りすぎて飽きたので、最近はスープカレーをガッとやってます。
今日は、キャベツと玉ねぎと豚肩が入ったスープカレー作っていきます。
とりあえず、肉をいい感じに切って、塩水につけておきます(ブライニング...?)。
下味つくとか、肉が柔らかくなるとか、そんな効果があるはず。
キャベツ半玉を切って、洗って、濡れたまま鍋に入れて火にかけて蒸しておきます。
15分ぐらい蒸していると、半分ぐらいまで量が減るんで、それまでは放置
その間に、玉ねぎに塩振って、多めの油で揚げ焼く勢いで火強めにして炒めてく
今日はこれぐらいでやめた。
これぐらいになるタイミングでキャベツがいい感じに蒸しあがってたりする。
これにスパイスを突っ込んでルウ的な何かを生成していく。
カレー粉、バジル、にんにく、チリペッパー、胡椒、ボーンブロスの素などなど...。
蒸しあがったキャベツにつっこみます
肉と水とケチャップとウスターソース、味見をしつつ塩を突っ込みます。
肉は焼いたほうが風味つくけど面倒なのでやめました。
あとは沸騰しないぐらいで火を止めて、予熱で肉に火が通ったぐらいで完成です。
盛ったらこんな感じになりました。
飲酒した後とかに飲むと最高って感じになれます。
これで平日を乗り切っていくぞい。 完
Alexaから家の家電を制御できるようにした際の格闘記録 その1 やりたいことの確認と購入した部品とライトの制御まで
あらまし
ざっくりこんなかんじでした
- 最近自宅作業が多くなってきて、家環境整えてきてえ〜というお気持ちが高まっていた
- 最近流行りなスマートホームってよさげやん。やってみたいやん。
- Raspberry Piかって、Alexaつっこめば1台で全部できそうやん?
- やっていき〜〜〜
やりたいこと
- Raspberry PiにAlexaを入れて、
- 音声制御でおうちの家電をいい感じに制御して、
- 快適なおうち生活を送っていきたいっ...!!!!!!
完成図
こんなかんじでイケるようになりました オフトゥンから出ずに暖房つけれるので最高ですね
Alexaパイセンから家電制御できるようにしたーーーーー!これで布団から出ずにエアコンいじったり、電気消せるーーー!
やったこと
一覧としてはこんな感じでした
- Raspberry Pi 3買った
- 必要な電子部品等を買った
- コンセントから電源とるライトをオンオフできるようにした
- エアコンを赤外線LEDで制御できるようにした
- Raspberry PiにAlexaを召喚
- MQTTサービスを利用して、AlexaからGPIOの操作をする
書いててクソ長くなって気力が死んだので、とりあえずライトの制御までを書いていきます
Raspberry Pi 3買った
普通にAmazonで買いました。
Raspberry Pi 3 Model B V1.2 (日本製) 国内正規代理店品
- 出版社/メーカー: Raspberry Pi
- 発売日: 2016/02/29
- メディア: Tools & Hardware
- この商品を含むブログを見る
ケースは個人的にイケメンと感じたのでこれにしました。
アップグレード!LOTW Raspberry Pi 3 2 専用アクリル・ケース カバー アップグレードRaspberry Pi Model B+ B(9 layers)(Black/黒)
- 出版社/メーカー: LOTW
- メディア: エレクトロニクス
- この商品を含むブログを見る
SDは家にあった32GBのをつかってみましたが、16GBぐらいでたぶん十分だった。
必要な電子部品等を買った
以下の部品らを秋月で買ってきました
- BME280使用 温湿度・気圧センサモジュールキット: センサ一般 秋月電子通商 電子部品 ネット通販
- 赤外線リモコン受信モジュール GP1UXC41QS: センサ一般 秋月電子通商 電子部品 ネット通販
- 3mm赤外線LED OSI5FU3A11C (10個入): LED(発光ダイオード) 秋月電子通商 電子部品 ネット通販
- ソリッド・ステート・リレー(SSR)キット 25A(20A)タイプ: 組立キット 秋月電子通商 電子部品 ネット通販
- 2石マイクアンプキット(プリアンプキット): 組立キット 秋月電子通商 電子部品 ネット通販
- エレクトレットコンデンサーマイクロホン(ECM) WM-61A相当品 リードピン付: パーツ一般 秋月電子通商 電子部品 ネット通販
- ヒューズホルダー(中継用) MF-520: パーツ一般 秋月電子通商 電子部品 ネット通販
あと、マイクをつなげるのに、USBのサウンドボードを買った
秋月で買わなかったけど、延長コードも1本必要でした 以下のような感じで、途中から裂いたりできるタイプ
コンセントから電源とるライトをオンオフできるようにした
机にある電気をラズパイから制御できるようにしてきます。 ソリッドステートリレーが活躍してくれます
写真を撮り忘れたんですけど、雰囲気は以下のブログのような感じです
物理の実装
とりあえず、物理層の実装はこんな感じです
- 秋月のソリッドステートリレーのキットを組み立てる
- コンセントの延長コードを準備して、適当な位置で真ん中を裂く
- 2本になったうち、片方のケーブルを切って、ソリッドステートリレーキットのACの+-部分につなぐ
- ソリッドステートリレーキットのDCの+-部分には、RaspberryPiにつなげれるようにする
- DCの+-部分はRaspberry PiのGPIOとGNDにつなぐ
これで準備はできた感じです。
回路に問題ないかを確認したかったら、角電池とバッテリースナップを準備して、DCのところに抜き差ししてみるとサクッと確認できて便利です
あとは、Raspberry PiのGPIOピンにDCの部分をつないで、GPIOをHIGH
にしてやると電気がつくはずです
アプリ層の実装
GPIOをいじってRaspberry Piからソリッドステートリレーをオンオフできるようにしてみます。
GPIOを操作するにはWritingPi
が導入ラクだし使うのラクだったので、使ってます。
導入は以下みたいなコマンドをぶったたけば終わるのでちょろいです
$ sudo apt-get install libi2c-dev git $ git clone git://git.drogon.net/wiringPi $ cd wiringPi $ ./build
実際にGPIOをHIGH
にしたりLOW
にする際は、こんなかんじでやります
$ gpio -g mode 18 out // BCM 18ピンをoutモードにする $ gpio -g write 18 1 // BCM 18ピンをHIGHにする
ピンの番号がわからないときは、gpio readall
を叩くとわかります
実際のピンに対応するBCM番号や、現在のモードと値がわかったりします。
例えば、さっきのコマンドを叩いたあとにgpio readall
してみると、
BCM 18に当たるGPIO.1
というnameの行がMode
がOUT
でV
が1
になっていたりします
$ gpio readall +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+ | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ | | | 3.3v | | | 1 || 2 | | | 5v | | | | 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | | | 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | | | 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 0 | IN | TxD | 15 | 14 | | | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 | | 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 1 | OUT | GPIO. 1 | 1 | 18 | | 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | | | 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | OUT | GPIO. 4 | 4 | 23 | | | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 | | 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | | | 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 | | 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 | | | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 | | 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 | | 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | | | 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 | | 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | | | 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 | | 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 | | | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 | +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
ここまでできたら、ソリッドステートリレーのDC部分をGPIO.1
とGND
につないでみると、ライトがついてくれるはず。
もし、つかなかったら、以下を確認してみましょう。
gpio readall
をして、繋いでいるところのGPIOのV
が1
になっているかを確認- さっきの例だと
GPIO.1
のV
が1
になっていればいい
- さっきの例だと
- DCのところに乾電池とかを繋いでみて、ライトが点灯するか
- GPIOの読む際、Raspberry Piの向きがあっているか
-私はこれをミスりまくって時間を溶かした
オフにする際は、V
を0
にすればよい
$ gpio -g write 18 0 // BCM 18ピンをLOWにする
こんなかんじで、Raspberry Piからライトをオンオフできるようになりました。
次の記事ではエアコンを制御したときのことを書こうと思います〜。
Raspberry Pi Zero Wのセットアップ
あらまし
最近、リモート勤務が多くなって、自宅にいる時間が長くなってきたので、家環境をいい感じにしたい気がしていました。 冬休みを長めに取ったし、冬休みのお勉強がてら、おうちハックをキメてこうと思って、Raspberry PiのZero Wと3を買いました。
今日はとりあえず、Zeroのほうのセットアップをしたので、忘備録として書いとこうと思います。
やったこと
- 家に既にあったRaspberry Piのホスト名を変えておく
- はんだ付けする
- イメージをSDに書き込む
- Host名を書き換える
家に既にあったRaspberry Piのホスト名を変えておく
私の家には、家に既にRaspberry Pi Model B
がある。
電源を入れてsshしようとすると、avahi-daemonで使っているホスト名が被って繋がらなさそうな気がした。
とりあえず、今稼働中のRaspberry Piのホスト名を変更する。
ホスト名を変更したければ、/etc/hosts
と/etc/hostname
に記載されているraspberrypi
という名前の箇所を任意に書き換えればいいので、書き換える。
今そのRaspberry Piは、低温調理機以外の運用をしていないので、sous-vide-cooker-pi
と命名しといた。
以下、元あったRaspberry Piの書き換えたファイル
$ cat /etc/hostname sous-vide-cooker-pi $ cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 sous-vide-cooker-pi
はんだ付けする
各種センサーを買ったりしたら、こいつを介して操作なり、値取得したいと思ったので、自前でピンをはんだ付けしとく。
はんだ付け最中に、カメラのコネクタ的な箇所を折ってしまった様子..........。
まあ、カメラつかわないと思うので、気にしないことにしておく。
イメージをSDに書き込む
とりあえず、本家からイメージをとってきます
デスクトップ環境はいらないので、LITEのほうを落としました
落としたイメージはEtcher
という便利ツールでSDに書き込みます。
OSXでSDのイメージ焼くのダルかった印象あるんですけど、これつかうとサクッといけて最高でした。
セットアップを進める際に、OTGという機能を使ってUSB経由でRaspberry Piの設定をいじりたいので、書き込んだSDの中にある2ファイルを書き換えておく。
cmdline.txt
rootwait
と quiet
の間に modules-load=dwc2,g_ether
を追記する
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=37665771-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether quiet init=/usr/lib/raspi-config/init_resize.sh
config.txt
末尾にdtoverlay=dwc2
を追加する
$ echo "dtoverlay=dwc2" >> /Volumes/boot/config.txt
ssh
sshできるようにするために、中身は空で良いのでssh
というファイルを作っておく
$ pwd /Volumes/boot $ touch ssh $ ls COPYING.linux bcm2708-rpi-0-w.dtb bcm2708-rpi-cm.dtb bcm2710-rpi-cm3.dtb config.txt fixup_db.dat kernel.img ssh start_db.elf LICENCE.broadcom bcm2708-rpi-b-plus.dtb bcm2709-rpi-2-b.dtb bootcode.bin fixup.dat fixup_x.dat kernel7.img start.elf start_x.elf LICENSE.oracle bcm2708-rpi-b.dtb bcm2710-rpi-3-b.dtb cmdline.txt fixup_cd.dat issue.txt overlays start_cd.elf
wifiの設定
wpa_supplicant.conf
というファイルにWiFiの設定を記述する
このファイルを作成しておくと、OS起動時に/etc/wpa_supplicant/wpa_supplicant.conf
を上書きしてくれるとのこと
country=JP ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="自分ちのWiFiのSSID" psk="対応するPW" }
ここまでできたら、Zero本体にSDカードをセットし、micro USBデータポートとPCのUSBポートを接続する
(ついでに購入していたケースに収めた)
OSXの「共有」の設定画面から「インターネット共有」を選択しRNDIS/Ethernet Gadget
をオンにして、「インターネット共有」をオンにする
ここまで一通り終えて何も問題なければ、USB経由でRaspberry Piにアクセスできるようになっている。
raspberrypi.local
にping
を飛ばすと、疎通が取れることを確認できる。
$ ping raspberrypi.local PING raspberrypi.local (192.168.2.2): 56 data bytes 64 bytes from 192.168.2.2: icmp_seq=0 ttl=64 time=0.418 ms 64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.437 ms 64 bytes from 192.168.2.2: icmp_seq=2 ttl=64 time=0.367 ms 64 bytes from 192.168.2.2: icmp_seq=3 ttl=64 time=0.334 ms 64 bytes from 192.168.2.2: icmp_seq=4 ttl=64 time=0.421 ms 64 bytes from 192.168.2.2: icmp_seq=5 ttl=64 time=0.317 ms ^C --- raspberrypi.local ping statistics --- 6 packets transmitted, 6 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.317/0.382/0.437/0.046 ms
で、疎通が確認できたのでSSHしてみる
が、前のRaspberry Piの設定が残ってて怒られた\(^o^)/
$ ssh pi@raspberrypi.local @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: POSSIBLE DNS SPOOFING DETECTED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The ECDSA host key for raspberrypi.local has changed, and the key for the corresponding IP address 192.168.2.3 is unknown. This could either mean that DNS SPOOFING is happening or the IP address for the host and its host key have changed at the same time. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is SHA256:OKg7/purvgRAstmPcBClMoguGxtTq/fYEXgsncrr+uA. Please contact your system administrator. Add correct host key in /Users/symmt/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /Users/symmt/.ssh/known_hosts:12 ECDSA host key for raspberrypi.local has changed and you have requested strict checking. Host key verification failed.
こうやって、以前のキーを無効にしておく
$ ssh-keygen -R raspberrypi.local # Host raspberrypi.local found: line 12 /Users/symmt/.ssh/known_hosts updated. Original contents retained as /Users/symmt/.ssh/known_hosts.old
これで、sshすると接続できるはず
ifconfig
して、WiFiもつながっていることを確認する
$ ifconfig lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 usb0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether be:00:90:c1:b0:26 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.10.105 netmask 255.255.255.0 broadcast 192.168.10.255 inet6 fe80::213:71d8:461d:dc5d prefixlen 64 scopeid 0x20<link> ether b8:27:eb:d3:1a:24 txqueuelen 1000 (Ethernet) RX packets 408 bytes 63330 (61.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 122 bytes 21324 (20.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Host名を書き換える
ホスト名が他のRaspberry Piと被らないように変更しておく
$ cat /etc/hostname raspberry-pi-zero $ cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspberry-pi-zero
変更したホスト名でping
できることを確認する
$ ping raspberry-pi-zero.local PING raspberry-pi-zero.local (192.168.2.7): 56 data bytes 64 bytes from 192.168.2.7: icmp_seq=0 ttl=64 time=0.694 ms 64 bytes from 192.168.2.7: icmp_seq=1 ttl=64 time=0.319 ms ^C --- raspberry-pi-zero.local ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.319/0.506/0.694/0.188 ms
これで一通りの設定はできたと思うので、おしまい そのうち電子工作したらまた書く
参考
マイクプリアンプを作った話
このブログ記事は、 Dark - Developers at Real Kommunity Advent Calendar 2017の9日目
の記事になります。
どちゃくそ遅れていまして、ごめんなさい〜〜〜〜〜〜〜〜〜〜〜。
今日は最近やったマイクプリアンプの話でも雑にしてます。
マイクプリアンプつくった経緯
私は歌うのが好きで、たまに歌ったやつを練習がてらスマホで録音したりするんですよね。
特にどこかに晒すわけでもなく、自分で聴ければいいやってレベルだったので、
スマホについてるマイクで録音をしていました。
そんな私なんですが、最近nana
ってサービスを知りました。
めっちゃ面白いじゃん!!!
って思って、スマホで録音したのを投稿してみたりしたんですけど、
使っているスマホのマイクなので、音質が気になり始めたんですね。
で、今はスマホ用のオーディオインターフェースがあったりするので、買ってみました。
TASCAM マイク ギターインターフェース iPad iPhone iPod touch用 iXZ
- 出版社/メーカー: TASCAM
- 発売日: 2011/09/23
- メディア: エレクトロニクス
- 購入: 2人 クリック: 9回
- この商品を含むブログを見る
ちなみに、マイクはコレです
- 出版社/メーカー: BEHRINGER
- メディア: エレクトロニクス
- 購入: 11人 クリック: 47回
- この商品を含むブログ (7件) を見る
これにダイナミックマイクをXLRケーブルで繋いで録音してみたんですが、ボリュームが小さい。
ボリュームをあげるには、マイクプリアンプというボリューム上げるくんが必要になるんですが、
これが買おうとすると安くても5,000円ぐらいするんですね。
既に3,000円つっこんで、更に5,000円突っ込む気にはなれない...。
でも、自作なら2,000円もかからずに作れるのでは?と思って、今回作ってみました。
必要な部品
実際に作るのに必要な部品は以下になりました
必要なもの | 金額 |
---|---|
プリアンプキット | 700円 |
XLRコネクタ(オス) | 324円 |
XLRコネクタ(メス) | 410円 |
配線 | 300円 |
スイッチ | 80円 |
バッテリースナップ | 20円 |
ダイソーに売ってたカードケース | 100円 |
で、合計金額1,934円
となり、2,000円いかなかったですね〜。
しかもこの必要なもの一覧、カードケース以外は全部学生の時に買って家に余ってたので、
追加出費したのは100円
で済みました。最高。
作り方
やったことはこんな感じ
- プリアンプキットの説明書を読みながらはんだ付けする
- カードケースに穴をあける
- がんばって部品を入れ込む
今回は、マイクプリアンプのキットを買ったので、説明書読んではんだ付けするだけで済みました!
キットをつかって作る分には、プラモデル感覚でモノが作れるので、最高です。
電子工作で一番の難関ぽいのは、個人的にはケースの準備だと思います。
私はよくダイソーにいって調達しています。
最近は、今回も利用しているアクリル製カードケースがめっちゃいいサイズで最高となっております。
ちなみに、穴開けたりするときは、タミヤのリューターを使ってます。
電池式で軽いしまあ便利です。
- 出版社/メーカー: タミヤ
- メディア: おもちゃ&ホビー
- 購入: 2人 クリック: 8回
- この商品を含むブログを見る
完成形
こんな感じでできました。
使うときはこんな感じで、マイクとオーディオインターフェース間にかませます。 ボリューム操作は、オーディオインターフェース側でよしなにします。
録音もいい感じの音量でできるようになって、最高でした。
おわりに
こういう電子工作は結構敷居高く感じられる人が多い印象ですけど、
説明書つきのキットなり、作りたいものの回路さえゲットしちゃえば、
難易度的にはプラモデルつくるのと、そう変わりないです。たぶん。
私はオーディオ系のものをつくるのが好きで結構ハマっていました。
マイクとかイヤホンが好きな人は、レシピがよく落ちてるので、つくってみるときっと楽しいです。
- ヘッドホンアンプの作り方
- マイクの作り方
最近はRaspberry Piと連携してIoTなこともできますし、
電子工作に触れてみると、プログラミングで遊べる幅も広がって楽しいですよ!
もうすぐ冬休みですし、暇な人はぜひRaspberry PiとLED買ってきてビカビカさせてみたりしてください。笑
Androidで不要そうなPermissionが取得されているので消した話@React Native Advent Calendar 2017
このブログは、React Native Advent Calendar 2017 - Qiitaの7日目の記事です。
私はAndroidがもうそろ1年ぐらいになるエンジニアです。
最近、ReactNativeを触ってアプリを書いていまして、
その際に気になった、AndroidのPermissionの話を書いてみようと思います。
Permissionが取られていることに気づいた
ReactNativeの新規プロジェクトを立ち上げて、
AndroidのmergeされたManifestを見てみると、
以下の3つのPermissionが取られていることに気づきました。
- WRITE_EXTERNAL_STORAGE
- READ_PHONE_STATE
- READ_EXTERNAL_STORAGE
自身のManifestに追加したわけでもないのにな〜〜〜。
あと、以下のPermissionが自分のアプリのManifestに追加されました。
- SYSTEM_ALERT_WINDOW
「なんだこいつら」
「必要なPermissionなんかコレ」
と調べたところ、いらなそうなんで消しときましょうという話です
なんで謎なPermissionが3つ取られているのか
まずは、以下の3つの権限の話からです
- WRITE_EXTERNAL_STORAGE
- READ_PHONE_STATE
- READ_EXTERNAL_STORAGE
ひとまずReactnativeのリポジトリを見てみたところ、
早速それっぽいIssueを見つけたので読んでみました。
以下はざっくりしたまとめです。
謎にPermissionが取得されている原因
- 問題の3つの権限は、
org.webkit.android_jsc
から取られていた- これはAndroid Studioで
Merged Manifest
を見てみるとわかるよ!
- これはAndroid Studioで
org.webkit.android_jsc
のAndroid Manifestには、minSdkVersion
とtargetSdkVersion
が設定されていなかった- そのせいで、デフォルト値が適用され、
minSdkVersion=1
targetSdkVersion=1
となっていた- 以下はドキュメントからの引用です
android:minSdkVersion 警告: この属性を宣言しないと、既定値の「1」と見なされ、アプリがすべてのバージョンの Android と互換性があるものとして扱われます。 アプリにすべてのバージョンとの互換性があるわけではない場合(たとえば、アプリが API レベル 3 で導入された API を使用、など)、適切な minSdkVersion を宣言しないと、API レベルが 3 未満の端末にインストールしたとき、使用できない API にアクセスしようとして実行時にアプリがクラッシュします。 このため、必ず minSdkVersion 属性で適切な API レベルを宣言するようにしてください。 uses-sdk | Android Developers
android:targetSdkVersion アプリのターゲットとなる API レベルを指定する整数。設定しない場合、既定値は minSdkVersion で指定した値になります。 uses-sdk | Android Developers
- 以下はドキュメントからの引用です
minSdkVersion
とtargetSdkVersion
が3以下
の場合、問題の3つの権限が暗黙的に付与されるようになっていた- 以下はドキュメントへのリンク
解決策
- 解決方法は、
org.webkit.android_jsc
のAndroid ManifestにminSdkVersion
とtargetSdkVersion
を設定すること
以下、かなしいお話
- 実は、その旨のPRは既に出していて、mergeもされている
- PRはmergeされているものの、リリースがされていない 😇
- PRのmerge後に続くコメントを読んだところ、こんなかんじだった
- FBの人「最初のリリース以降、更新してないからリリースフローがないんすわ 😇」
- 最初にリリースした人にメンションつけて、どうすればいいんや、と聞く
- 最初にリリースした人「やる気あったら、あんたリリースしちゃってくれ 😇」
- そのまま放置.....
- FBの人「最初のリリース以降、更新してないからリリースフローがないんすわ 😇」
- その後も、FB組に「進捗どう?」的なコメントを投げるも音沙汰なし 😇
対応策
現状、属性マーカー(Attribute Marker)を利用して消すしかなさそう 😇
以下を参考に、実例
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="xxx.xxx.xxx"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
というわけで、とりあえずこれで対応することにします 😇
SYSTEM_ALERT_WINDOWは必要なのか...?
次は、SYSTEM_ALERT_WINDOW
の話です。
この権限は、WarningやCrashをデバッグ時に画面に表示するために取られていたPermissionのようです。
つまり、デバッグビルドのときは欲しいけど、リリースビルドでは特に必要のないものです。
消してしまいましょう!!!!
以下を参考に、実例
app/src/release/AndroidManifest.xml
にRelease Build用のmanifestをつくる
中身は以下のような感じ
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" > <uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" /> </manifest>
これで、リリース時にはSYSTEM_ALERT_WINDOW
のPermission消せる
まとめ
ReactNativeで最初から付与されているPermission群の削除は、
app/src/main/AndroidManifest.xml
を以下のようにすると消せるよ
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="xxx.xxx.xxx"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> ... </manifest>
SYSTEM_ALERT_WINDOW
のPermissionは、デバッグ時以外は不要なので、
以下の内容でapp/src/release/AndroidManifest.xml
にRelease Build用のManifestをつくるといいよ
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" > <uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" /> </manifest>
低温調理機をつくったお話 @低温調理 Advent Calendar 2017
この記事は、低温調理 Advent Calendar 2017の3日目の記事です。
盛大に遅刻しました。ごめんなさい。
低温調理機をつくった話をします
低温調理機は常々ほしいと思っていたのですが、そこそこ値段するんですよね。
それっぽいものつくれないかなと思って調べたら、イケそうな気がしたのでつくりました。
7月くらいには、勉強会で発表ネタにもしてみてみました。
今回は、その時の発表内容を文字起こししていく感じでやっていきます。
低温調理機の構成
実装のために、低温調理機の構成を考えてみます。
以下の4要素あればイケる気がしました。
- コンピュータ
- 温度を見て、水温を一定に保つ
- ヒーター
- 水温を上げる
- 温度計
- 水温を測る
- 撹拌機
- 水温を全体的に均一にする
で、実装にあたって今回はこんな感じでやりました
- コンピュータ
- ヒーター
- 水槽用ヒータ
- 温度計
- 1-wireでデータを取れる水温計
- 撹拌機
- 水槽用ポンプ
これらを購入してきて、実際に低温調理機をつくってみました。
実装(物理)
回路図等飛ばして、完成写真はこんな感じになります。
実際に低温調理機をつくるのに、だいたい以下のものを買いました。
物品 | 価格 | 備考 |
---|---|---|
Raspberry Pi | 600円ぐらい~5,000円ぐらい | 温度制御用(私は初代を持ってたのでそれつかった) |
水槽用ヒータ | 1,680円@amazon | 水を温める |
ソリッドステートリレー | 800円@秋月 | ヒータのオンオフ制御用 |
ヒューズ | 30円@秋月 | 事故防止用。5Aでよかったかは謎。 |
延長コード | 100円 | 途中にヒューズをかませて、電源とヒータの間につかう |
水温計 | 263円@amazon | 水温測るのにつかった |
水槽用ポンプ | 677円@amazon | 水を撹拌するのにつかう |
バケツ | 300円 | 水槽つくる用 |
私はRaspberry Piを元々持っていたので、それを抜くと4,000円ぐらいで作れました。
雑に説明すると、こんな構成になっています。
- 延長コードにヒューズとソリッドステートリレーをかませ、水槽用ヒーターをつなぐ
- バケツに水を張り、ポンプを設置する
- ソリッドステートリレーと水温計をRaspberry Piにつないでおく
物理層自体はそんなもんで、
あとは温度制御をするためのプログラムを準備すると調理機になってくれます。
実装(コード)
実際のコードは以下に公開してます。
Symfony3(PHP)で書いてあって、
設定した温度に合わせて、ヒーターをON/OFFして温度制御してくれます。
PHPが書ければ、肉を調理することができる便利な時代になりました。
こんな感じでAPIを叩くと調理が始まる感じになっています。
$ curl -sS -X POST http://127.0.0.1:8000/cooking/status {"message":"The cooking does not begin yet."} $ curl -sS -X POST http://127.0.0.1:8000/cooking/start --data 'cookingTemperature=56' --data 'cookingTime=09:00:00' --data 'description=ローストビーフ' {"isCooking":true,"CookingTime":"09:00:00","CookingTemperature":56,"CurrentTemperature":"55.562","CookingStartTime":"2017-06-26 23:38:04","CookingEndTime":"2017-06-27 08:38:04","description":"\u30ed\u30fc\u30b9\u30c8\u30d3\u30fc\u30d5"}% $ curl -sS -X POST http://127.0.0.1:8000/cooking/status | jq . { "isCooking": true, "CookingTime": "09:00:00", "CookingTemperature": 56, "CurrentTemperature": "55.375", "CookingStartTime": "2017-06-26 23:38:04", "CookingEndTime": "2017-06-27 08:38:04", "description": "ローストビーフ" }
APIはここらへんに書いてあります。
実際の温度制御はここらへんに書いてあります。
PI制御するようにしていて、実装は@hamanoさんのブログを参考にしました。
雑ですが、そんな感じで低温調理機が完成しました。
補足:温度計の校正
調理機自体はできたのですが、温度計の校正をしとくと、なお良いです。
使っているセンサーの温度をそのまま流用すると、誤差があったりすることがあります。
なので、稼働前に信頼できそうな温度計を準備して、
購入したセンサーで取得した温度と差分がないかをチェックしておくといいと思います。
簡単な方法としては、沸騰したお湯にセンサーをつっこんで、
100度からどれくらい差分があるかを確認する方法かと思います。
差分があったら、その分プラマイしておくと、正確そうな温度がとれる気がします。
自分の書いたプログラムだと、
Serviceのパラメータに補正値を登録しといて、温度取得の際に補正してます。
テスト稼働
完成して、めでたいので、肉をアレしてみましょう。
豚肩ロースを買ってきました。
これを、ニンニクとか黒胡椒とかを入れた塩分濃度1%ぐらいの塩水に1晩つけときます。
人間は塩分濃度0.8%ぐらいが丁度いい塩加減と感じるそうです。
なので、それに近そうな濃度にしときます。
調理機に突っ込みます。
63℃で3時間ぐらいやっときました。
取り出して切ってみた様子です。
ちょっとギッチギチに詰めすぎたようで、場所によって火の通りが違いました。
つっこみすぎに気を付けましょう。
左から右に行くほど、火が入っていて、肉が縮んでパサついております。
私的には、一番左の肉塊がいい感じでした。
焼き色を付けるといい匂いがして美味しく感じるものなので、
煙出るほど熱した鉄フライパンでジュッと焼いておきます。
そんなわけで、美味しく調理できました。
完成写真については、写真を撮り忘れていて無いです\(^o^)/←
とりあえず、美味しかったので、成功です。
豚肩ロースは結構美味しくできるのでおすすめです。
わさびつけて食べると美味しいです。
おわりに
ぶっちゃけ、買ったほうがラクですけど、自分で調理機つくるのは楽しかったです。
Raspberry Piとやっていきな気持ちがあれば作れるので、ぜひやってみてください。
おまけ: 風呂ーストビーフをつくる
低温調理してみたいけど、こんなにいろいろやるのはダルい方に朗報です。
ご自宅の給湯器で温度を 75℃程度まであげれれば、お風呂で低温調理ができます!
やり方は簡単です。
- 給湯器の温度を75度ぐらいに設定する
- お風呂にお湯を張る
- 密封した肉を風呂に放り込む
- 水温的に、牛ももがいい感じです
- 3時間程度放置する
- 回収して、焼き色をつけてカットして完成
この日はローストビーフ丼にしました。
光景がなかなかフォトジェニックですが、お肉は美味しくできました。
お風呂に入れないぐらいのお湯を張ったときにでもやってみてください。
参考にしたものリンク
ExoPlayerでMediaSessionをいい感じに扱う
概要
ExoPlayerを使って音楽再生しようとしてた
んで、MediaSessionを使っていき〜〜〜〜というふうになっていた
「色々書いてくの、めんどくさいな〜〜〜〜」と思っていたところ、そこらへんをよしなにしてくれるextensionがあると知った
他のブログとか特に見つからず、公式ブログを読んでも、パッと理解できなかったので、動作確認できたコードを残しておく
ExoPlayerのExtensionを使っていいかんじにやっていく
例にあげたコードは以下を元にしています
- Building a Media Browser Service | Android Developers
- Responding to Media Buttons | Android Developers
Before
public class MediaPlaybackService extends MediaBrowserServiceCompat { private static final String MY_MEDIA_ROOT_ID = "media_root_id"; private static final String MY_EMPTY_MEDIA_ROOT_ID = "empty_root_id"; private MediaSessionCompat mMediaSession; private PlaybackStateCompat.Builder mStateBuilder; @Override public void onCreate() { super.onCreate(); // Create a MediaSessionCompat mMediaSession = new MediaSessionCompat(context, LOG_TAG); // Enable callbacks from MediaButtons and TransportControls mMediaSession.setFlags( MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); // Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player mStateBuilder = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE); mMediaSession.setPlaybackState(mStateBuilder.build()); // MySessionCallback() has methods that handle callbacks from a media controller mMediaSession.setCallback(new MySessionCallback()); // Set the session's token so that client activities can communicate with it. setSessionToken(mMediaSession.getSessionToken()); // MediaSession to active. mMediaSession.setActive(true); } @Override public int onStartCommand(Intent intent, int flags, int startId) { MediaButtonReceiver.handleIntent(mMediaSession, intent); return START_NOT_STICKY; } }
After
こんな感じでPlaybackStateCompat.Builder
とMySessionCallback
がいらなくなる
public class MediaPlaybackService extends MediaBrowserServiceCompat { private static final String MY_MEDIA_ROOT_ID = "media_root_id"; private static final String MY_EMPTY_MEDIA_ROOT_ID = "empty_root_id"; private MediaSessionCompat mMediaSession; private PlaybackStateCompat.Builder mStateBuilder; private SimpleExoPlayer mPlayer; @Override public void onCreate() { super.onCreate(); mPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector()); setBroadcastReceiver(); mAudioPlayer = new AudioPlayer(this); mAudioPlayerNotification = new AudioPlayerNotification(this); // Create a MediaSessionCompat mMediaSession = new MediaSessionCompat(this, LOG_TAG); // Enable callbacks from MediaButtons and TransportControls mMediaSession.setFlags( MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); // Set the session's token so that client activities can communicate with it. setSessionToken(mMediaSession.getSessionToken()); // Used MediaSession extension MediaSessionConnector mediaSessionConnector = new MediaSessionConnector(mMediaSession); mediaSessionConnector.setPlayer(mPlayer, null); // MediaSession to active. mMediaSession.setActive(true); } @Override public int onStartCommand(Intent intent, int flags, int startId) { MediaButtonReceiver.handleIntent(mMediaSession, intent); return START_NOT_STICKY; } }
補足
再生/一時停止
、再生
、一時停止
、秒送り
をしたいときは、PlaybackController
を自前で実装して、
mediaSessionConnector = MediaSessionConnector(MediaSessionCompat mediaSession,PlaybackController playbackController)
すればよさそう
曲送りやら、ランダム再生やらをしたいときは、QueueNavigator
を実装して
mediaSessionConnector.setQueueNavigator(QueueNavigator queueNavigator)
とすればよさそう
おわりに
ExoPlayerのドキュメント、超読みにくかったり、欲しい情報どこにあるのか謎な問題、あるとおもいます