tag:crieit.net,2005:https://crieit.net/tags/RaspberryPi/feed 「RaspberryPi」の記事 - Crieit Crieitでタグ「RaspberryPi」に投稿された最近の記事 2024-02-27T00:48:40+09:00 https://crieit.net/tags/RaspberryPi/feed tag:crieit.net,2005:PublicArticle/18777 2024-02-27T00:46:48+09:00 2024-02-27T00:48:40+09:00 https://crieit.net/posts/Raspberry-Pi-5-Ubuntu-24-04-LTS-SSH Raspberry Pi 5 に Ubuntu 24.04 LTS を入れて SSH するまで <p>ついに日本でも、 Raspberry Pi 5 の技適対応モデルが発売された。</p> <p>Raspberry Pi にインストールする OS と言えば、まずは <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.com/software/">Raspberry Pi OS (旧 Raspbian)</a> だが、同じ Debian ベースの <a target="_blank" rel="nofollow noopener" href="https://ubuntu.com/download/raspberry-pi">Ubuntu</a> も Raspberry Pi 向けの公式イメージを出している。</p> <p>但し、 Raspberry Pi 5 に対応しているのは、 Ubuntu 23.10 (コードネーム: mantic) 以降のみとなる。</p> <p>現在リリース済みの 23.10 は「非LTS」バージョンとなり、サポートが 9ヶ月 (2024年6月まで) と短い。<br /> 常用するなら、サポートが 5年 (ESM なら 10年) と長い LTS バージョンが望ましいが、残念ながら 22.04 LTS Raspberry Pi 5 に非対応だ。</p> <p>LTS バージョンの次回リリースは 24.04 LTS (コードネーム: noble / 2024年4月リリース予定) で、現在絶賛開発中だ。</p> <p>そんな開発中の 24.04 LTS も、デイリースナップショットが手に入る。<br /> そいつを使って<strong>ディスプレイやキーボードが無い状態</strong>で、インストールから SSH 接続までやってみよう。</p> <p>Raspberry Pi 5 をターゲットに書いているが、 Raspberry Pi 3, 4, Raspberry Pi Zero 2 W でも同じ手順でできるはずだ。</p> <p>なお、この記事は 24.04 LTS がリリースされたら、それに併せて内容に書き換えていくつもり。</p> <h2 id="TL;DR"><a href="#TL%3BDR">TL;DR</a></h2> <ul> <li>microSD カードに Ubuntu の OS イメージを焼いたあと、 RasPi に挿す<strong>前</strong>に初回起動時の設定を書き換える</li> <li>cloud-init の挙動を理解しよう</li> <li>ディスプレイなし & 無線LAN Only だと少し工夫がいる</li> <li>今回の記事の内容は、<a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1404">Raspberry Pi に Ubuntu を入れて SSH でログインするまでの A to B | Aqua Ware つぶやきブログ</a> の二番煎じ <ul> <li>Ubuntu 24.04 LTS に合わせて内容はアップデートされている</li> </ul></li> </ul> <h2 id="準備するもの"><a href="#%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE">準備するもの</a></h2> <ul> <li>Raspberry Pi 5 <ul> <li>Raspberry Pi 3, 4 でも同じ手順でいけるはず</li> </ul></li> <li>4GB 以上の micorSD カード <ul> <li>IOPS が高い、「アプリケーションパフォーマンスクラス」が A2 のものが良いだろう。値段や速度を考えると、実用上は 64GB 以上になるだろうか。</li> <li>私は、<a target="_blank" rel="nofollow noopener" href="https://amzn.to/42J1AeI">ARCANITE 64GB microSDXCカード 【A2】、UHS-I U3、V30、4K、C10</a> 値段の割にパフォーマンスが良かったため、これを使った。</li> <li>後述するが、最終的には NVMe SSD にした方が断然良い</li> </ul></li> <li>microSD を書き込める PC (Win, Linux, mac)</li> <li>インターネットに繋がる Wi-Fi または イーサネットケーブル</li> </ul> <p>以下もあると便利だが、今回の手順では無くても問題ない。</p> <ul> <li>micro-HDMI で繋がるディスプレイ 又は 変換コネクタ</li> <li>RasPi に繋げる USB キーボード</li> </ul> <h2 id="イメージファイルの取得"><a href="#%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%8F%96%E5%BE%97">イメージファイルの取得</a></h2> <p>正式リリース前の Raspberry Pi 向けデイリースナップショットイメージは、以下のいずれかから手に入る。</p> <p>今回は、サーバーOS的に SSH して使う事が目的なので、<strong>後者のサーバー版</strong>を利用する。</p> <ul> <li>Raspberry Pi 向けデスクトップ版イメージ <ul> <li><a target="_blank" rel="nofollow noopener" href="https://cdimage.ubuntu.com/daily-preinstalled/current/">https://cdimage.ubuntu.com/daily-preinstalled/current/</a></li> </ul></li> <li>Raspberry Pi や、汎用 64-bit ARM, RISC-V 向けサーバー版イメージ <ul> <li><a target="_blank" rel="nofollow noopener" href="https://cdimage.ubuntu.com/ubuntu-server/daily-preinstalled/current/">https://cdimage.ubuntu.com/ubuntu-server/daily-preinstalled/current/</a></li> </ul></li> </ul> <p>リンク先から、 <code>noble-preinstalled-server-arm64+raspi.img.xz</code> を選択してダウンロードしよう。</p> <p>24.04 LTS が正式リリースされれば、 <a target="_blank" rel="nofollow noopener" href="https://ubuntu.com/download/raspberry-pi">Install Ubuntu on a Raspberry Pi | Ubuntu</a> のページからダウンロードできるようになるはずだ。</p> <h2 id="ブータブル SD の焼き込み"><a href="#%E3%83%96%E3%83%BC%E3%82%BF%E3%83%96%E3%83%AB+SD+%E3%81%AE%E7%84%BC%E3%81%8D%E8%BE%BC%E3%81%BF">ブータブル SD の焼き込み</a></h2> <p>ダウンロードしたイメージファイルを、ブート可能な状態で microSD に書き込む。<br /> ダウンロードしたファイルをただ SD カードに保存するのではなく、専用のツールで書き込む必要があるぞ。</p> <p>方法は色々あるのだが、今回は個人的にオススメな <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/etcher/">balenaEtcher</a> を使った方法で紹介しよう。</p> <ol> <li>microSD を SDカードスロットに挿す</li> <li>balenaEtcher を DL & 起動する。 <ul> <li>DLする balenaEtcher は Portable 版で良い</li> </ul></li> <li>前項でダウンロードするした <code>***.img.xz</code> を選択して、書き込みを開始する <ul> <li><code>***.img.xz</code> は、 <code>***.img</code> ファイルを <code>.xz</code> 形式で圧縮したものなのだが、手動で解凍せず直接 balenaEtcher で選択してしまって問題ない。 balenaEtcher は書き込み時にオンザフライで解凍する。</li> </ul></li> </ol> <p>なお、リリース済みの Ubuntu (や Raspberry Pi OS など) であれば、一般的に <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.com/software/">Raspberry Pi Imager</a> というツールを使った方法がオススメされるのだが、DLが遅いからか、全体的に時間がかかるので私はあまりオススメしない。</p> <h2 id="system-boot パーティション内の cloud-init 等の設定を書き換える"><a href="#system-boot+%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E5%86%85%E3%81%AE+cloud-init+%E7%AD%89%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%8B">system-boot パーティション内の cloud-init 等の設定を書き換える</a></h2> <p>作成した micorSD を早速 RasPi に挿す <strong>…前に</strong> 、 初回セットアップ設定を書き換える。</p> <p>一度書き込んだ microSD を再び PC に挿し直すと、 <code>"system-boot"</code> という 500MB 位の FAT32 パーティションが開けるはずだ。</p> <p>ここには、 cloud-init という仕組みで初回起動時の設定を定義するファイルがいくつか含まれている。<br /> これらを書き換えていく。</p> <p>書き換え後のファイルは <a target="_blank" rel="nofollow noopener" href="https://gist.github.com/advanceboy/c9b020fe09ababd390c0e95d74dfde7e">こちらの Gist</a> に置いてあるので、結果だけ欲しい人はここから DL をば。</p> <h3 id="cloud-init の network-config"><a href="#cloud-init+%E3%81%AE+network-config">cloud-init の network-config</a></h3> <p>以下のように書き換える。<br /> (元のファイルからの差分を <code>diff</code> のフォーマットで表示している。 以降同様。)</p> <pre><code class="diff">--- network-config.org +++ network-config @@ -22,23 +22,11 @@ ethernets: eth0: dhcp4: true optional: true -# wifis: -# wlan0: -# dhcp4: true -# optional: true -# access-points: -# myhomewifi: -# password: "S3kr1t" -# myworkwifi: -# password: "correct battery horse staple" -# workssid: -# auth: -# key-management: eap -# method: peap -# identity: "[email protected]" -# password: "passw0rd" -# ca-certificate: /etc/my_ca.pem - -# regulatory-domain: GB + wifis: + wlan0: + dhcp4: true + access-points: + "SSID-of-myhomewifi": + password: "password-of-myhomewifi" </code></pre> <p>Ubuntu では Netplan を使ってネットワークが管理されるため、 Netplan の形式で記述する。</p> <p>規定値では IPv4 の有線イーサネットのみ、 DHCP 自動取得で接続されるようになっている。<br /> 必要に応じて、上述のように Wi-Fi で接続する SSID 等の情報を追記したり、逆に有線LANを使わないなら <code>ethernet:</code> プロパティごと削除してしまってもよいだろう。</p> <p>SSID やパスワードは、各自の環境のものに置き換えて書き換えてほしい。</p> <p>コメントアウトされている wifi の記述例では、 <code>wifis.wlan0.optional</code> を <code>true</code> に設定しているが、もし Wi-Fi 単独でネットワークに接続するつもりならこの設定は行わないようにしよう。<br /> さもないと、OS起動の度に2分も余計に時間かかる羽目になる。<br /> これは、 <code>systemd-networkd-wait-online.service</code> デーモンが、(optional true を指定していない) 有効なネットワークの接続をタイムアウトするまで待機してしまうためだ。</p> <p>network-config 自体のリファレンスはこちら。<br /> <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/23.4.1/reference/network-config.html">https://cloudinit.readthedocs.io/en/23.4.1/reference/network-config.html</a></p> <h3 id="cloud-init の user-data"><a href="#cloud-init+%E3%81%AE+user-data">cloud-init の user-data</a></h3> <p>こちらは書き換え箇所が多いので、何箇所かに分けて説明していく。</p> <p>まず最初はユーザー名まわり。</p> <pre><code class="diff">--- user-data.org +++ user-data @@ -17,13 +17,17 @@ # Some additional examples are provided in comments below the default # configuration. +# Override the `default_user` configuration from `/etc/cloud/cloud.cfg`. The `user` dictionary keys supported for the default_user are the same as the `users` schema. +user: + name: newusername + # On first boot, set the (default) ubuntu user's password to "ubuntu" and # expire user passwords chpasswd: expire: true users: - - name: ubuntu - password: ubuntu + - name: newusername + password: newpassword type: text ## Set the system's hostname. Please note that, unless you have a local DNS </code></pre> <p>規定では、 cloud-init パッケージの <code>/etc/cloud/cloud.cfg</code> ファイルの定義によって、 "ubuntu" というユーザーが作成される。</p> <p>しかし、 既知のユーザー名をそのまま使うのはセキュリティ的にも若干不安があるし、 作成後のユーザー名を書き換えるのは若干面倒なので、作成されるデフォルトのユーザー名自体を、他の名前 (上記例だと "newusername") に書き換えてしまおう。</p> <p>また、 <code>chpasswd</code> による、初回アクセス時のパスワード変更対象とするユーザー名も、併せて変更しておく。</p> <p>--</p> <p>次にホスト名とキーボード周りの設定。</p> <pre><code class="diff">@@ -31,14 +35,14 @@ ## setting the hostname here will not make the machine reachable by this name. ## You may also wish to install avahi-daemon (see the "packages:" key below) ## to make your machine reachable by the .local domain -#hostname: ubuntu +hostname: ubuntu-raspi5 ## Set up the keyboard layout. See localectl(1), in particular the various ## list-x11-* sub-commands, to determine the available models, layouts, ## variants, and options -#keyboard: -# model: pc105 -# layout: gb +keyboard: + model: pc105 + layout: jp # variant: # options: ctrl:nocaps </code></pre> <p>ここはまぁ、見た通りなので追加での説明はいらないかな。</p> <p>--</p> <p>お次は SSH まわり。</p> <pre><code class="diff">@@ -53,6 +57,8 @@ #ssh_import_id: #- lp:my_launchpad_username #- gh:my_github_username +ssh_authorized_keys: +- ssh-rsa AAAA<中略>== rsa-key-of-user1 ## Add users and groups to the system, and import keys with the ssh-import-id ## utility </code></pre> <p><code>ssh_authorized_keys</code> に直接指定するか、<code>ssh_import_id:</code> のところで自分の GitHub のユーザー名を指定してインポートすることにより、 デフォルトのユーザー (上記例だと "newusername") に登録する公開鍵を指定する。</p> <p>SSH に登録するパスワードログインは規定で禁止されているので、この設定をしておかないと SSH による遠隔からのアクセスができない。</p> <p>--</p> <p>タイムゾーンや起動後の処理まわり。</p> <pre><code class="diff">@@ -82,8 +88,13 @@ #- python3-gpiozero #- [python3-serial, 3.5-1] +# locale and timezone +timezone: Asia/Tokyo + ## Write arbitrary files to the file-system (including binaries!) -#write_files: +write_files: +- path: /etc/cloud/cloud-init.disabled + defer: true #- path: /etc/default/console-setup # content: | # # Consult the console-setup(5) manual page. </code></pre> <p>とりあえずタイムゾーンは日本標準時にしておこう。</p> <p>次に、 <code>write_files:</code> のほうだが、これは次回以降のブート時に cloud-init が余計に起動しないようにするための設定だ。</p> <p>cloud-init の設定の大半は、 初回ブート時にただ一度だけ実行されるのだが、 cloud-init サービス自体は基本的に毎回常に起動して、サービスとして常駐しっぱなしになっている。<br /> <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/modules.html">Modules</a> で、 <code>Module frequency: per always</code> となっているモジュールの実行などは、ブートする度に毎回実行される。<br /> そうすると、場合によっては cloud-init の実行ログがログイン画面を覆ってしまうことが毎回の起動ごとに発生して鬱陶しい。<br /> このため、 <code>/etc/cloud/cloud-init.disabled</code> という <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/howto/disable_cloud_init.html#method-1-text-file">空ファイルを作成しておく</a> ことで、 次回以降の起動時に cloud-init を無効にしている。</p> <p><code>defer: true</code> が指定されている部分についてだが、これは cloud-init の初期化処理が大きく分けて Network (<code>cloud_init_modules</code>), Config (<code>cloud_config_modules</code>), Final (<code>cloud_final_modules</code>) という <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/explanation/boot.html">3ステージ に分かれて</a> いることに関係する。<br /> <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files"><code>write_files:</code> モジュール</a> は Ubuntu の既定だと Network ステージに実行されてしまい、このタイミングで <code>cloud-init.disabled</code> ファイルが作成されてしまうと、 Config や Final ステージの処理が実行されなくなってしまう。<br /> このため、 <code>defer</code> オプションを true にして Final ステージで <code>cloud-init.disabled</code> ファイルが作成されるよう調整しているのだ。</p> <p>なお、どのモジュールがどのステージで実行されるかは、 <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/reference/base_config_reference.html#example"><code>/etc/cloud/cloud.cfg</code></a> で定義されている。<br /> (各ディストリビューション毎の <a target="_blank" rel="nofollow noopener" href="https://git.launchpad.net/ubuntu/+source/cloud-init/tree/config/cloud.cfg.tmpl?h=ubuntu/noble"><code>cloud.cfg</code> のテンプレートソースはこちら</a>)</p> <hr /> <p>最後に、コマンドの実行。<br /> 以下の <code>192.168.0.2</code> の部分は、 ssh で RasPi に接続するゲスト PC の IPアドレス に書き換えてくれ。</p> <pre><code class="diff">@@ -106,7 +117,9 @@ # permissions: '0644' ## Run arbitrary commands at rc.local like time -#runcmd: +runcmd: +# after wlan0 is connected, write the arp entry to target machine on background job +- [ sh, -c, 'sleep 2; ping -c 4 192.168.0.2' ] #- [ ls, -l, / ] #- [ sh, -xc, "echo $(date) ': hello world!'" ] #- [ wget, "http://ubuntu.com", -O, /run/mydir/index.html ] </code></pre> <p>このコマンドは、仮に ssh ゲストの IP アドレスが <code>192.168.0.2</code> であると仮定して、そこへ向かって Ping を打っている。<br /> なぜなら、 ゲストPC から RaspPi の IP アドレスを ARP コマンドで確実に調べられるようにするためだ。</p> <p>RasPi に繋げるディスプレイがないことを前提とすると、 SSH するために DHCP によって RasPi に割り当てられた IP アドレスをどうやって調べるのか、と言う問題に直面する。</p> <p>RasPi の MAC アドレスの先頭 24bit は、 Raspberry 財団の所持する OUI から割り当てられるはずなので、以下のいずれかになるはずだ。</p> <pre><code>28:CD:C1 2C:CF:67 B8:27:EB D8:3A:DD DC:A6:32 E4:5F:01 </code></pre> <p>通常、 RasPi がオンラインになったときに、 ARPリクエストがブロードキャストされるため、 同一ネットワーク内の PC の ARP テーブルに RasPi のレコードが追加され、 以下のような arp コマンドで対象の IP アドレスを調べることができるようになる。。。 <strong>多くの場合は。</strong></p> <pre><code class="powershell">while(1) { arp -a | ?{ $_ -match '\s(28-cd-c1|2c-cf-67|b8-27-eb|d8-3a-dd|dc-a6-32|e4-5f-01)' }; Start-Sleep -Seconds 1} </code></pre> <p>ところが、 RasPi が Wi-Fi で繋いでいる先が (単なるアクセスポイントではなく) ルーターだったりすると、 RasPi が 同じサブネット内に ARPリクエスト をブロードキャストしたのにも関わらず、 ルーターが無駄に気を利かせて ARPリクエスト を代替して投げてしまい、 同じサブネットの別の端末の ARP テーブルには、 RasPi の MAC アドレスのレコードが記録されないことがある。</p> <p>そこで、 RasPi 側から SSH のアクセス元となる PC を指定して ping を投げることで、 その PC の ARP テーブルに確実に RasPi が載るようにしている。</p> <p>--</p> <p>ここまで書き換えたら、 SD カードを取り外して RasPi に挿し、いよいよ起動する。</p> <h3 id="cloud-init 周りの補足"><a href="#cloud-init+%E5%91%A8%E3%82%8A%E3%81%AE%E8%A3%9C%E8%B6%B3">cloud-init 周りの補足</a></h3> <p>system-boot パーティション内の中身について、もう少し細かい仕組み周りを深堀りして補足したい。<br /> 興味が無ければ、読み飛ばしてしまって次の章に進んでもらって問題ない。</p> <p>system-boot パーティション直下にある <code>README</code> というファイルを開くと、このパーティションに存在するファイルの概要が簡単に書いてある。</p> <pre><code class="text:README">================== The Boot Partition ================== This file belongs to the boot partition of the Ubuntu Server for Raspberry Pi. ... </code></pre> <p>このパーティションには、Raspberry Pi に於ける BIOS の代替となる <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.com/documentation/computers/config_txt.html">config.txt</a> といった H/W 設定用のファイルや、 cloud-init の構成ファイルなどが含まれていることがわかる。</p> <p>このうち、<strong>cloud-init</strong> は Infrastructure as Code (IaC) の一種だ。<br /> その名の通り、 AWS などのクラウド上の仮想マシンの初期設定を念頭においた仕組みだが、それに留まらず、一般的な Linux インスタンスの初期設定に活用される。<br /> 設定内容は、YAML形式の設定ファイルを使用して記述し、クラウドやディストリビューションの違いをある程度吸収して初期設定を行うことができる。<br /> Ubuntu の OS のイメージ内には、事前に cloud-init のサービス(デーモン)が組み込まれており、OS の起動時に何らかの方法で指定された設定ファイルを読み取って、初回設定処理が実行される仕組みとなっている。</p> <p>Raspberry Pi 用の Ubuntu Server イメージでは、この cloud-init 用の設定ファイルが上記の <code>system-boot</code> パーティションから取得される。<br /> イメージ内のデフォルト値の定義と、<code>system-boot</code> パーティション内のユーザー定義が組み合わされ、初期設定が進められるワケだ。</p> <p>たとえば、今回 microSD に書き込んだイメージをそのまま書き換えずに Ubuntu を起動すると、ユーザー認証が以下のように構成される。</p> <ol> <li><code>ubuntu</code> というユーザーID</li> <li><code>ubuntu</code> というパスワード</li> <li>初回起動時にパスワードの変更を求める</li> <li>SSH サーバーの起動</li> </ol> <p>このうち、 (1), (4) は、OSに組み込まれた <code>/etc/cloud/cloud.cfg</code> の定義によるもの。<br /> そして、 (2), (3) は <code>system-boot</code> パーティション内の <code>user-data</code> ファイル内の以下の部分の定義によるモノだ。</p> <pre><code class="yaml:user-data">#cloud-config chpasswd: expire: true users: - name: ubuntu password: ubuntu type: text </code></pre> <p>このデフォルトの構成だと流石にセキュリティ的にアレなので、書き換えを行っている… というのが、前項の設定の真相となる。</p> <h2 id="Raspberry Pi に割り当てられた IP アドレスを調べられるようにして起動"><a href="#Raspberry+Pi+%E3%81%AB%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%89%E3%82%8C%E3%81%9F+IP+%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%89%E3%82%8C%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%97%E3%81%A6%E8%B5%B7%E5%8B%95">Raspberry Pi に割り当てられた IP アドレスを調べられるようにして起動</a></h2> <p>こんな感じでひととおりファイルを書き換えたら、いよいよ RasPi を起動する。</p> <p>…と、その前に、 ssh でつなぐ予定のゲスト端末で、管理者権限で以下のコマンドを実行し、端末内の「arp テーブル」をリセットする。</p> <pre><code class="powershell">arp -d * </code></pre> <p>その後、ようやくだが RasPi に microSD を挿して起動させよう。<br /> 初回ブート時の設定を適用しながら起動してくれる。</p> <p>ssh でつなぐ予定のゲスト端末の PowerShell で、以下のような arp コマンドのループを実行し、ゲストPC から RasPi の IPアドレスを調べよう。<br /> 初回起動され安定しただろうところ(SDカードの I/O 性能によるが 1~5分?)で、 RasPi の IP アドレスがヒットしてくるようになるはずだ。</p> <pre><code class="powershell">while(1) { arp -a | ?{ $_ -match '\s(28-cd-c1|2c-cf-67|b8-27-eb|d8-3a-dd|dc-a6-32|e4-5f-01)' }; Start-Sleep -Seconds 1} </code></pre> <p>公開鍵の登録が適切に行えれば、その IP アドレスに対し SSH できるはずだ。</p> <p>初回アクセス時は、以下のようなパスワード変更を求められる。</p> <pre><code>WARNING: Your password has expired. You must change your password now and login again! Changing password for newusername. </code></pre> <p>古いパスワード ("newpassword") と変更後のパスワードを改めて入れる。</p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>一般的な1列端子の microSD で最速な UHS-I SDR104 のバスインターフェースに Raspberry Pi 5 が対応したことや、最近の安価な microSD の I/O 速度もだいぶ向上したのも相まって、 RasPi 4B が登場した頃と比べると、体感できる I/O 性能が大きく向上している。<br /> おかげで、起動やパッケージのインストール、更新などが快適になった。</p> <p>だいぶ高価になってしまった価格的な面からも、 Raspberry Pi の 非Zero/Pico シリーズは「Linuxが動くマイコン」から「小型のLinuxマシン」という面がより強くなったと感じる。<br /> (それはどうなんだという気もするけど。)</p> <p>更に RasPi 5 では PCI Express (PCIe) にも対応しているため、 NVMe で繋いだ SSD からブートさせると、更に桁違いの高速化が臨める。</p> <p>近いうちに、そちらも試してみようと思う。</p> <p>…ただ、どうせ PCIe に対応するなら、microSD Express に対応してくれれば、 NVMe 用 HAT とか買い足さんで済むから良かったのにな~…と、思わんでもない。<br /> しかし、2019年にSD7.1の規格として登場してから4年も経った2024年現在その製品が売られているとこを見たことないので、まぁ無理な相談か。</p> advanceboy tag:crieit.net,2005:PublicArticle/16980 2021-04-22T13:33:58+09:00 2021-04-23T09:31:27+09:00 https://crieit.net/posts/Raspberry-Pi-APRS-I-GATE-Raspberry-Pi-USB 【Raspberry Pi】APRS I-GATE局をRaspberry PiとUSBワンセグチューナーで構築する その1【アマチュア無線】 <h1 id="APRSとは?"><a href="#APRS%E3%81%A8%E3%81%AF%EF%BC%9F">APRSとは?</a></h1> <p>Automatic Position Reporting Systemの略。</p> <p>最近マイブームとなっているAPRS。<br /> 名称の通り自動的に一定間隔で位置情報を送信してくれます。<br /> アマチュア無線の主に144MHz帯が使われていて1200bpsは144.66MHz、9600bpsは144.64MHzを使うという慣習があります。</p> <h1 id="I-GATE局について"><a href="#I-GATE%E5%B1%80%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">I-GATE局について</a></h1> <p>この位置情報をインターネット上に流して<a target="_blank" rel="nofollow noopener" href="https://ja.aprs.fi/#!lat=35.9489&lng=139.6444">googleマップに表示させることができます。</a><br /> ネットと無線のインターフェイスの役割を果たすのがI-GATE局で、ほかにもパケットを中継するデジピーターというものもあります。</p> <p>従来はWindows PCに専用のソフトを入れて無線機や受信機に繋ぐ必要があったのですが<br /> この方法では消費電力が大きく場所も取りPCも無線機も高価です。<br /> そこで比較的安価で低消費電力なRaspberry PiとUSBワンセグチューナーを利用しI-GATE局を構築します。</p> <h1 id="用意するもの"><a href="#%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE">用意するもの</a></h1> <ul> <li>Raspberry pi       なんでもいいですzeroでも動きます。</li> <li>microSDカード      容量はそんなに大きくなくていいです。</li> <li>ACアダプター      ちゃんと2A以上のものを使いましょう。</li> <li>USBワンセグチューナー RTL2832かそれと同等なチップが積んであるもの</li> <li>延長USBケーブル    なくてもいいですがラズパイにチューナー直刺しだと<br />              精神衛生上よくないので気になる方にはお勧めです。<br /> <a href="https://crieit.now.sh/upload_images/1d3fa3a1adac65d1080698a43b2fd1d46080e04d8c022.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1d3fa3a1adac65d1080698a43b2fd1d46080e04d8c022.jpg?mw=700" alt="SDR" /></a><br /> ↑ワンセグチューナーと同じチップを積み無線受信用にカスタマイズされたUSBドングル。</li> </ul> <h1 id="ソフトウェアのインストール"><a href="#%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">ソフトウェアのインストール</a></h1> <h2 id="rtl_sdrのインストール"><a href="#rtl_sdr%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">rtl_sdrのインストール</a></h2> <p>Raspberry Piのセットアップはほかのサイトを見ていただくとしてこのページでは<br /> ソフトウェアのインストールから説明します。</p> <p>まずUSBワンセグチューナーを受信機として動作させるためにrtl_sdrというソフトを入れます。</p> <pre><code class="sh">sudo apt-get install rtl_sdr </code></pre> <p>正しくインストールできたかテストするためにFM放送を聞いてみましょう。<br /> TOKYO FM 80.0MHzを受信する場合。</p> <pre><code class="sh"> rtl_fm -M wbfm -f 80000000 -g 42 | aplay -r 32k -f S16_LE -t raw -c 1 </code></pre> <p>これでラジオが流れてくればインストールは成功です。</p> <h2 id="DireWolfのインストール"><a href="#DireWolf%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">DireWolfのインストール</a></h2> <p>次にAPRS信号の復調とパケットの転送を行うソフトをインストールします。</p> <pre><code class="sh"> sudo apt-get install direwolf </code></pre> <h1 id="次回予告"><a href="#%E6%AC%A1%E5%9B%9E%E4%BA%88%E5%91%8A">次回予告</a></h1> <p>今回はいったんここまで。<del>やる気の糸が切れた</del><br /> 次回はDire Wolfの設定とラズパイを起動したときにDire Wolfとrtl_sdrが自動起動するようにします。</p> MSK tag:crieit.net,2005:PublicArticle/16474 2021-01-03T17:44:02+09:00 2021-02-08T12:57:52+09:00 https://crieit.net/posts/Raspberry-Pi-Slack-5ff183d2eaf81 【Raspberry Pi】解錠・施錠をSlackへ通知する仕組みを作る <p><strong>本記事は2020/02/03に作成したものです。<br /> 最新の環境ではうまく動作しない可能性がありますのでご注意ください。</strong></p> <p>これは部屋の施錠状態をメンバーへ周知するために作ったものです。<br /> 解錠や施錠を行った時にタクトスイッチを押すことで、Slackへその旨を通知します。<br /> 以前はAmaz◯nダッシュボタンでやっていたのですが、サービス廃止に伴いラズパイとタクトスイッチで作り直しました。</p> <p>slackの「Incoming Webhook」の設定は済んでいることを前提にしています<br /> ※現在は非推奨になっている「カスタムインテグレーション」で作成した「Incoming Webhook」で動作確認しています。</p> <h2 id="動作確認済み環境"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83">動作確認済み環境</a></h2> <ul> <li>Raspberry Pi 3 Model B+</li> <li>Raspbian 9.4 stretch (日本語環境)</li> </ul> <h2 id="slack通知イメージ"><a href="#slack%E9%80%9A%E7%9F%A5%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8">slack通知イメージ</a></h2> <p><a href="https://crieit.now.sh/upload_images/c04b3fcb7db1277b2bfe262d2e0664e85ff182134b7f4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c04b3fcb7db1277b2bfe262d2e0664e85ff182134b7f4.png?mw=700" alt="5f48d5f13f70e9fabd60272e70e4ef76.png" /></a></p> <h2 id="GPIOとスイッチの接続"><a href="#GPIO%E3%81%A8%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%81%AE%E6%8E%A5%E7%B6%9A">GPIOとスイッチの接続</a></h2> <p>暫定運用なのでブレッドボードで作っています<br /> <a href="https://crieit.now.sh/upload_images/5f8fb065b75a83e1c827765e0a2e4f615ff1822b40b00.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5f8fb065b75a83e1c827765e0a2e4f615ff1822b40b00.png?mw=700" alt="a0cce0bc8eaaa253120c74a8ac82dbfa.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/98bed6a57a1ce78704aebcd56a9b74c55ff1823d0e2a4.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/98bed6a57a1ce78704aebcd56a9b74c55ff1823d0e2a4.jpg?mw=700" alt="ecabf0ea125319cbc1848f73759ecb4e.jpg" /></a></p> <h2 id="slackwebインストール"><a href="#slackweb%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">slackwebインストール</a></h2> <p>回路ができたらコードの作成をします<br /> まずはSlack通知に使うモジュールをpipでインストールします</p> <pre><code class="bash">$ pip3 install slackweb </code></pre> <h2 id="ボタン押されたらslackへ通知するコード"><a href="#%E3%83%9C%E3%82%BF%E3%83%B3%E6%8A%BC%E3%81%95%E3%82%8C%E3%81%9F%E3%82%89slack%E3%81%B8%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89">ボタン押されたらslackへ通知するコード</a></h2> <p>Slack通知に使うコードを作成します</p> <h3 id="/home/pi/lock2slack.py"><a href="#%2Fhome%2Fpi%2Flock2slack.py">/home/pi/lock2slack.py</a></h3> <pre><code class="Python">#!/usr/bin/env python3 import RPi.GPIO as GPIO from time import sleep import slackweb UNLOCK = 20 LOCK = 21 slack = slackweb.Slack(url="https://hooks.slack.com/services/xxxx/xxxx/xxxx") #Incoming Webhookのurlをここへ記述します MSG_UNLOCK = "研修室解錠しましたにゃ" MSG_LOCK = "研修室施錠しましたにゃ" SLACK_NAME = "RaspberryPiボタンさん" GPIO.setwarnings(False) GPIO.cleanup() GPIO.setmode(GPIO.BCM) GPIO.setup(UNLOCK, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(LOCK, GPIO.IN, pull_up_down=GPIO.PUD_UP) def sw_unlock(ch): slack.notify(text=MSG_UNLOCK, username=SLACK_NAME) def sw_lock(ch): slack.notify(text=MSG_LOCK, username=SLACK_NAME) GPIO.add_event_detect(UNLOCK, GPIO.RISING, callback=sw_unlock, bouncetime=500) GPIO.add_event_detect(LOCK, GPIO.RISING, callback=sw_lock, bouncetime=500) while True: sleep(0.1) </code></pre> <h2 id="lock2slack.pyに実行権限を追加する"><a href="#lock2slack.py%E3%81%AB%E5%AE%9F%E8%A1%8C%E6%A8%A9%E9%99%90%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B">lock2slack.pyに実行権限を追加する</a></h2> <pre><code class="bash">$ chmod +x /home/pi/lock2slack.py </code></pre> <h2 id="rc.localを使ってOS起動時にコードを実行させる"><a href="#rc.local%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6OS%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AB%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B">rc.localを使ってOS起動時にコードを実行させる</a></h2> <pre><code class="bash">$ sudo vi /etc/rc.local </code></pre> <h3 id="rc.localの中身"><a href="#rc.local%E3%81%AE%E4%B8%AD%E8%BA%AB">rc.localの中身</a></h3> <p>rc.localに書くやり方は古いですが手軽なので</p> <pre><code>#!/bin/bash -e sudo -u pi /usr/bin/python3 /home/pi/lock2slack.py & exit 0 </code></pre> <p>あとは、OSを再起動させて動作確認ができたら完了です</p> arohajiro tag:crieit.net,2005:PublicArticle/16473 2021-01-03T17:34:29+09:00 2021-03-01T07:56:03+09:00 https://crieit.net/posts/Raspberry-Pi-xrdp 【Raspberry Pi】xrdpをインストールする <p>ラズパイのGUIに、MacやWindowsからのリモートデスクトップクライアントで接続できます。</p> <h1 id="動作確認済み環境"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83">動作確認済み環境</a></h1> <p>Raspberry Pi 3 Model B+<br /> Raspbian 9.4 stretch (日本語環境)<br /> Microsoft Remote Desktop 10.3.7 (macOS)</p> <h1 id="xrdpインストール"><a href="#xrdp%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">xrdpインストール</a></h1> <pre><code class="bash">$ sudo apt -y install xrdp </code></pre> <h1 id="xrdpのステータス確認"><a href="#xrdp%E3%81%AE%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E7%A2%BA%E8%AA%8D">xrdpのステータス確認</a></h1> <pre><code class="bash">$ sudo systemctl status xrdp </code></pre> <h2 id="ステータス出力例"><a href="#%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E5%87%BA%E5%8A%9B%E4%BE%8B">ステータス出力例</a></h2> <p><strong>active (running)</strong>なら問題なく起動していますので<br /> PCからリモートデスクトップ接続が可能です。</p> <pre><code>● xrdp.service - xrdp daemon Loaded: loaded (/lib/systemd/system/xrdp.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-02-03 02:34:39 UTC; 1min 23s ago Docs: man:xrdp(8) man:xrdp.ini(5) Main PID: 1376 (xrdp) CGroup: /system.slice/xrdp.service └─1376 /usr/sbin/xrdp </code></pre> <p>なお、リモートデスクトップ接続ではGUIメニューからOSのシャットダウンができないので<br /> シャットダウンしたい時はコマンドで実施します。</p> arohajiro tag:crieit.net,2005:PublicArticle/16468 2021-01-03T17:03:40+09:00 2021-01-15T12:03:12+09:00 https://crieit.net/posts/Raspberry-Pi-Raspberry-Pi-2-rclone 【Raspberry Pi】Raspberry Piをデジタルサイネージ風に使う その2 (rclone導入) <p><strong>本記事は2019/12/27に作成したものです。<br /> 最新の環境ではうまく動作しない可能性がありますのでご注意ください。</strong></p> <p><a href="https://crieit.net/posts/Raspberry-Pi-Raspberry-Pi-1">その1の記事</a> で作成したデジタルサイネージを運用しはじめたところ、以下の悩みが発生しました。。。</p> <p><strong>サイネージのコンテンツ更新のたびに、pdfのスライドを毎度アップロードするのがしんどい!</strong></p> <p>なので、Google ドライブとrcloneを使って、今まで手動でアップロードしていた作業を自動化しました。<br /> Google ドライブの指定ディレクトリをrcloneで同期させるスクリプトを定期実行させる仕組みです。</p> <h2 id="動作確認済み環境"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83">動作確認済み環境</a></h2> <p>Raspberry Pi 3 Model B+<br /> Raspbian 9.4 stretch (日本語環境)<br /> rclone v1.50.2</p> <h2 id="必要な設定の流れ"><a href="#%E5%BF%85%E8%A6%81%E3%81%AA%E8%A8%AD%E5%AE%9A%E3%81%AE%E6%B5%81%E3%82%8C">必要な設定の流れ</a></h2> <ul> <li>rcloneのインストールと設定</li> <li>rcloneを使ったGoogle ドライブ同期スクリプト作成</li> <li>Google ドライブ同期スクリプトを定期実行させるためのcron作成</li> </ul> <h2 id="rcloneのインストールと設定"><a href="#rclone%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E8%A8%AD%E5%AE%9A">rcloneのインストールと設定</a></h2> <h3 id="rcloneのインストール"><a href="#rclone%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">rcloneのインストール</a></h3> <pre><code class="bash">$ curl https://rclone.org/install.sh | sudo bash </code></pre> <h3 id="rcloneの設定"><a href="#rclone%E3%81%AE%E8%A8%AD%E5%AE%9A">rcloneの設定</a></h3> <pre><code class="bash">$ rclone config </code></pre> <p>以下対話形式で進めます</p> <h3 id="1. 新規なので、nを選択する"><a href="#1.+%E6%96%B0%E8%A6%8F%E3%81%AA%E3%81%AE%E3%81%A7%E3%80%81n%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">1. 新規なので、nを選択する</a></h3> <pre><code>2019/12/27 10:50:07 NOTICE: Config file "/home/pi/.config/rclone/rclone.conf" not found - using defaults No remotes found - make a new one n) New remote s) Set configuration password q) Quit config n/s/q> n </code></pre> <h3 id="2. 適当に名前をつける"><a href="#2.+%E9%81%A9%E5%BD%93%E3%81%AB%E5%90%8D%E5%89%8D%E3%82%92%E3%81%A4%E3%81%91%E3%82%8B">2. 適当に名前をつける</a></h3> <pre><code>name> drive </code></pre> <h3 id="3. Google ドライブを使うので、13を選択する"><a href="#3.+Google+%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%82%92%E4%BD%BF%E3%81%86%E3%81%AE%E3%81%A7%E3%80%8113%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">3. Google ドライブを使うので、13を選択する</a></h3> <pre><code>Type of storage to configure. Enter a string value. Press Enter for the default (""). Choose a number from below, or type in your own value 多いので省略 13 / Google Drive \ "drive" 多いので省略 Storage> 13 </code></pre> <h3 id="4. Client Idは、未入力でEnter"><a href="#4.+Client+Id%E3%81%AF%E3%80%81%E6%9C%AA%E5%85%A5%E5%8A%9B%E3%81%A7Enter">4. Client Idは、未入力でEnter</a></h3> <pre><code>Google Application Client Id Setting your own is recommended. See https://rclone.org/drive/#making-your-own-client-id for how to create your own. If you leave this blank, it will use an internal key which is low performance. Enter a string value. Press Enter for the default (""). client_id> </code></pre> <h3 id="5. client_secretは、未入力でEnter"><a href="#5.+client_secret%E3%81%AF%E3%80%81%E6%9C%AA%E5%85%A5%E5%8A%9B%E3%81%A7Enter">5. client_secretは、未入力でEnter</a></h3> <pre><code>Google Application Client Secret Setting your own is recommended. Enter a string value. Press Enter for the default (""). client_secret> </code></pre> <h3 id="6. Google ドライブからファイルを取り出せればいいので、Read-onlyの2を選択する"><a href="#6.+Google+%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%81%8B%E3%82%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%9B%E3%82%8C%E3%81%B0%E3%81%84%E3%81%84%E3%81%AE%E3%81%A7%E3%80%81Read-only%E3%81%AE2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">6. Google ドライブからファイルを取り出せればいいので、Read-onlyの2を選択する</a></h3> <pre><code>Scope that rclone should use when requesting access from drive. Enter a string value. Press Enter for the default (""). Choose a number from below, or type in your own value 1 / Full access all files, excluding Application Data Folder. \ "drive" 2 / Read-only access to file metadata and file contents. \ "drive.readonly" / Access to files created by rclone only. 3 | These are visible in the drive website. | File authorization is revoked when the user deauthorizes the app. \ "drive.file" / Allows read and write access to the Application Data folder. 4 | This is not visible in the drive website. \ "drive.appfolder" / Allows read-only access to file metadata but 5 | does not allow any access to read or download file content. \ "drive.metadata.readonly" scope> 2 </code></pre> <h3 id="7. root_folder_idは、未入力でEnter"><a href="#7.+root_folder_id%E3%81%AF%E3%80%81%E6%9C%AA%E5%85%A5%E5%8A%9B%E3%81%A7Enter">7. root_folder_idは、未入力でEnter</a></h3> <pre><code>ID of the root folder Leave blank normally. Fill in to access "Computers" folders (see docs), or for rclone to use a non root folder as its starting point. Note that if this is blank, the first time rclone runs it will fill it in with the ID of the root folder. Enter a string value. Press Enter for the default (""). root_folder_id> </code></pre> <h3 id="8. service_account_fileは、未入力でEnter"><a href="#8.+service_account_file%E3%81%AF%E3%80%81%E6%9C%AA%E5%85%A5%E5%8A%9B%E3%81%A7Enter">8. service_account_fileは、未入力でEnter</a></h3> <pre><code>Service Account Credentials JSON file path Leave blank normally. Needed only if you want use SA instead of interactive login. Enter a string value. Press Enter for the default (""). service_account_file> </code></pre> <h3 id="9. advanced configは、編集しないのでnを選択する"><a href="#9.+advanced+config%E3%81%AF%E3%80%81%E7%B7%A8%E9%9B%86%E3%81%97%E3%81%AA%E3%81%84%E3%81%AE%E3%81%A7n%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">9. advanced configは、編集しないのでnを選択する</a></h3> <pre><code>Edit advanced config? (y/n) y) Yes n) No y/n> n </code></pre> <h3 id="10. auto configは、使用しないのでnを選択する"><a href="#10.+auto+config%E3%81%AF%E3%80%81%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%AA%E3%81%84%E3%81%AE%E3%81%A7n%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">10. auto configは、使用しないのでnを選択する</a></h3> <pre><code>Remote config Use auto config? * Say Y if not sure * Say N if you are working on a remote or headless machine y) Yes n) No y/n> n </code></pre> <h3 id="11. rcloneがGoogle ドライブへアクセスするために必要なverification codeを入手する"><a href="#11.+rclone%E3%81%8CGoogle+%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%81%B8%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB%E5%BF%85%E8%A6%81%E3%81%AAverification+code%E3%82%92%E5%85%A5%E6%89%8B%E3%81%99%E3%82%8B">11. rcloneがGoogle ドライブへアクセスするために必要なverification codeを入手する</a></h3> <pre><code>If your browser doesn't open automatically go to the following link: https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=(省略) Log in and authorize rclone for access Enter verification code> </code></pre> <p>go to the following link: の後のURLをコピーし、WebブラウザでコピーしたURLへ接続します。<br /> 画面の指示にしたがってGoogleアカウントの認証とrcloneのアクセス許可を与えてください。<br /> 最後に、表示されたコードをコピーして、Enter verification codeに貼り付けます。</p> <h3 id="12. team driveは使わないのでnを選択する"><a href="#12.+team+drive%E3%81%AF%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E3%81%AE%E3%81%A7n%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">12. team driveは使わないのでnを選択する</a></h3> <pre><code>Configure this as a team drive? y) Yes n) No y/n> n </code></pre> <h3 id="13. 設定内容が表示されるので、yを選択する"><a href="#13.+%E8%A8%AD%E5%AE%9A%E5%86%85%E5%AE%B9%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E3%81%AE%E3%81%A7%E3%80%81y%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">13. 設定内容が表示されるので、yを選択する</a></h3> <pre><code>-------------------- [drive] type = drive scope = drive.readonly token = {"access_token":"(省略)"} -------------------- y) Yes this is OK e) Edit this remote d) Delete this remote y/e/d> y </code></pre> <h3 id="14. 設定から抜けるため、qを選択する"><a href="#14.+%E8%A8%AD%E5%AE%9A%E3%81%8B%E3%82%89%E6%8A%9C%E3%81%91%E3%82%8B%E3%81%9F%E3%82%81%E3%80%81q%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B">14. 設定から抜けるため、qを選択する</a></h3> <pre><code>Current remotes: Name Type ==== ==== drive drive e) Edit existing remote n) New remote d) Delete remote r) Rename remote c) Copy remote s) Set configuration password q) Quit config e/n/d/r/c/s/q> q </code></pre> <h3 id="15. 動作テスト"><a href="#15.+%E5%8B%95%E4%BD%9C%E3%83%86%E3%82%B9%E3%83%88">15. 動作テスト</a></h3> <p>ラズパイから、Google ドライブに作成しておいたディレクトリの参照ができることを確認します<br /> (以下例はGoogle ドライブのsinageディレクトリを参照しています)</p> <pre><code class="bash">$ rclone ls drive:sinage 1565471 slide.pdf </code></pre> <h2 id="rcloneを使ったGoogle ドライブ同期スクリプト作成"><a href="#rclone%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FGoogle+%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E5%90%8C%E6%9C%9F%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E4%BD%9C%E6%88%90">rcloneを使ったGoogle ドライブ同期スクリプト作成</a></h2> <h3 id="スクリプト置き場の作成"><a href="#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E7%BD%AE%E3%81%8D%E5%A0%B4%E3%81%AE%E4%BD%9C%E6%88%90">スクリプト置き場の作成</a></h3> <pre><code class="bash">$ mkdir /home/pi/cron </code></pre> <h3 id="スクリプトの作成"><a href="#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90">スクリプトの作成</a></h3> <pre><code class="bash">$ vi /home/pi/cron/syncsinage.sh </code></pre> <p>syncsinage.shの中身<br /> (Google ドライブのsinageディレクトリを/home/pi/sinage/へ同期させています)</p> <pre><code>#!/bin/bash rclone sync drive:sinage /home/pi/sinage/ </code></pre> <h3 id="スクリプトの実行権限付与"><a href="#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%AE%E5%AE%9F%E8%A1%8C%E6%A8%A9%E9%99%90%E4%BB%98%E4%B8%8E">スクリプトの実行権限付与</a></h3> <pre><code class="bash">$ chmod 744 /home/pi/cron/syncsinage.sh </code></pre> <h2 id="Google ドライブ同期スクリプトを定期実行させるためのcron作成"><a href="#Google+%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E5%90%8C%E6%9C%9F%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9A%E6%9C%9F%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEcron%E4%BD%9C%E6%88%90">Google ドライブ同期スクリプトを定期実行させるためのcron作成</a></h2> <h3 id="cron作成エディタ起動"><a href="#cron%E4%BD%9C%E6%88%90%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E8%B5%B7%E5%8B%95">cron作成エディタ起動</a></h3> <p>使うエディタの選択はお好みで...</p> <pre><code class="bash">$ crontab -e </code></pre> <p>cronの中身<br /> (5分おきにsyncsinage.shを実行させています)</p> <pre><code>SHELL=/bin/bash ### sync gdrive to sinage */5 * * * * /home/pi/cron/syncsinage.sh </code></pre> <p><strong>以上で作業は完了です!</strong><br /> これで面倒なアップロード作業とはお別れできました!<br /> あとは、ラズパイ起動時に自動でスライドショーを始める方法を探したいと思います。<br /> これができたら、もっと運用が楽になりそうです。</p> arohajiro tag:crieit.net,2005:PublicArticle/16456 2021-01-01T05:43:33+09:00 2021-01-01T11:29:59+09:00 https://crieit.net/posts/Raspberry-Pi-5fee37f5d34e8 Raspberry Pi で作るネットワークエミュレータ <p>明けましておめでとうございます。</p> <p>この記事は、 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2020/raspberry-pi">Raspberry Pi Advent Calendar 2020</a> 24日目の記事だ。<br /> <strong>…遅刻すぎるのもいいとこだわ。</strong></p> <hr /> <p>さて、ネットワーク回りの仕事をしていると、意図的にネットワークの遅延やパケロスを発生させて、検証したくなる状況がままある。</p> <p>対象のサーバーにネットワークを遅延させるようなモジュール入れるようなやり方も考えられるが、もっと手軽に、 LAN ケーブルの間に挟むだけで、そこを通る通信が全て遅延するみたいな、そんな機材が欲しくなる。</p> <p>もちろん、そのような需要があれば、それに応える製品があるわけで、それらは一般的に「ネットワークエミュレータ」として売られている。<br /> しかし、高いものでは数百万を軽く超え、安くても数万円はするものばかりだ。</p> <p>なんか安く作れないかなぁ…<br /> <strong>Raspberry Pi あたりで。</strong></p> <p>…ということで、 Raspberry Pi 4 を使って、遅延とパケロスを制御できる、お手軽ネットワークエミュレータを作ってみよう。</p> <h2 id="先駆者"><a href="#%E5%85%88%E9%A7%86%E8%80%85">先駆者</a></h2> <p>そもそもなのだが、そのものズバリなことを実践している先駆者様がいらっしゃった。</p> <p><a target="_blank" rel="nofollow noopener" href="http://dsas.blog.klab.org/archives/raspi-netem1.html">ラズパイで作るネットワークエミュレータ(前編) </a></p> <p>この記事の Raspberry Pi には、小型ドットマトリックス LCD ディスプレイや、様々な物理キーが GPIO に繋がっていて、 THE IoT という仕上がりになっている。</p> <p>かっこいいと思う。<br /> <strong>でも、電子工作するのめんどくさいよね。</strong></p> <h2 id="GUIで手っ取り早く作る"><a href="#GUI%E3%81%A7%E6%89%8B%E3%81%A3%E5%8F%96%E3%82%8A%E6%97%A9%E3%81%8F%E4%BD%9C%E3%82%8B">GUIで手っ取り早く作る</a></h2> <p>そんな複雑 (…というほど複雑でもないけど) な電子工作しなくても、 RasPi にタッチパネルディスプレイつけちゃえばいいじゃん。<br /> …ということで、 Amazon で割と評判のよい、 OSOYOO の 2,980円 タッチスクリーン付き LCD を取り付けて、めっちゃ簡単な UI をつくってみよう。</p> <p><a target="_blank" rel="nofollow noopener" href="https://amzn.to/3punHkf">OSOYOO(オソヨー) HDMI 3.5 インチ LCD ディスプレイ IPS モニター IPSタッチスクリーン 1920x1280ハイビジョン Raspberry Pi 4 3 2 Model B に対応 (3.5" HDMI LCD+クリアケース) </a></p> <p>もはや、 <strong>IoT 感を感じるのが難しく</strong>なってしまっているな……</p> <p>構成は、以下の図のように有線 LAN 2つ をブリッジ接続させる。</p> <p><img src="https://www.plantuml.com/plantuml/svg/TP9DRi8m44RtFiKKiMWNRWXjDrLKqN81n1e96SS1IydOjPqYLB5fxj13z0IzJovIs_n04CrgvlcDyzdoo3fcN5sLv4OYB-jSGEPgpNBpa71LLGfVhgmK2XrbQs5L9UXJOfZL2s7CPgxbkQwAGdAHZ1LoePrDh30V7ioPrgNapCcmkn7SCLoM0dfJLJjXUi0ic5WILBddat4QeUOfaUXvmRZ74A5T7wtXtXgItJXGUbhE-fsOCvmUMfX8U7oBiq6Hy4d0VsV1skQxRNxQfcc_Vk5sOGPtqVR5thtmXLiDeX6AVuJq8AH7mPyFGk83y2NGxXwXWVlkM6Y0XdD7jBrCd_MlNVmC9nktKWYlMk_kRREi9Jd-9AEqYz8JUWR7uJsNbiyml1A6kILRCXAO-wVq1m00" alt="" /></p> <p>これなら、 Raspberry Pi OS の標準の機能だけで実現できそうだ。</p> <p>なお設計的には、 Raspberry Pi が 2, 3, 4 どれでも機能するとは思うが、 1000BASE-T や USB 3.0 のポートを持っている Raspberry Pi 4B がオススメ。</p> <p>RasPi 4B には 1つ しか 有線LAN ポートがないので、適当にもう一つ USB 有線LAN アダプタをつける必要がある。<br /> Gigabit 対応のアダプタが良いだろう。</p> <h3 id="Raspberry Pi のセットアップ"><a href="#Raspberry+Pi+%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97">Raspberry Pi のセットアップ</a></h3> <p>まず、 <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/software/operating-systems/">Raspberry Pi OS with desktop</a> イメージを SD カードに焼く。<br /> "and recommended software" <strong>ではない</strong> ほうでかまわない。</p> <p>今回は、 <code>2020-12-02-raspios-buster-armhf.img</code> のバージョンのイメージで試した。</p> <p>OS イメージを焼くツールは何でも良いが、 <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/etcher/">balenaEtcher</a> あたりが良いだろう。</p> <p>Raspberry Pi OS が起動したら、以下の手順に従って、タッチスクリーンのドライバーが動くようにしておく。<br /> <a target="_blank" rel="nofollow noopener" href="http://osoyoo.com/ja/?p=4244">http://osoyoo.com/ja/?p=4244</a></p> <h3 id="Raspberry Pi の2つの有線NICでブリッジ"><a href="#Raspberry+Pi+%E3%81%AE2%E3%81%A4%E3%81%AE%E6%9C%89%E7%B7%9ANIC%E3%81%A7%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8">Raspberry Pi の2つの有線NICでブリッジ</a></h3> <p>まず接続されている、 NIC のインターフェイス名を確認する。</p> <pre><code class="console">$ ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 4: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 </code></pre> <p>Raspberry Pi の 有線LAN インターフェイスの場合は、 eth0, eth1... と名前がついていくため、 ここでは eth0, eth1 がブリッジ接続させる対象だとわかる。</p> <p>続いて、 <code>ip</code> コマンドを使って、ブリッジの作成する。</p> <pre><code class="console">$ sudo ip link add br0 type bridge $ sudo ip link set dev br0 up $ sudo ip link set dev eth0 promisc on $ sudo ip link set dev eth0 up $ sudo ip link set dev eth0 master br0 $ sudo ip link set dev eth1 promisc on $ sudo ip link set dev eth1 up $ sudo ip link set dev eth1 master br0 </code></pre> <p>※: ip link コマンドで設定したブリッジ設定は、 Raspberry Pi を再起動するとリセットされる。 起動時に自動設定させたければ Raspberry Pi OS であれば <code>/etc/network/interfaces.d/</code> 以下に、 Ubuntu であれば <code>/etc/netplan/</code> 以下に、 設定を書いておけば良いはず。</p> <p>この状態でブリッジが意図したとおり機能しているか、 PC1, PC2 を接続して iperf で速度を測ってみる。</p> <pre><code>> .\iperf3.exe -c PC2 Connecting to host 192.168.1.222, port 5201 [ 4] local 192.168.1.111 port 59582 connected to 192.168.1.222 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 53.6 MBytes 449 Mbits/sec [ 4] 1.00-2.00 sec 56.9 MBytes 478 Mbits/sec [ 4] 2.00-3.00 sec 58.0 MBytes 486 Mbits/sec [ 4] 3.00-4.00 sec 57.1 MBytes 479 Mbits/sec [ 4] 4.00-5.00 sec 57.9 MBytes 487 Mbits/sec [ 4] 5.00-6.00 sec 58.6 MBytes 491 Mbits/sec [ 4] 6.00-7.00 sec 57.6 MBytes 483 Mbits/sec [ 4] 7.00-8.00 sec 55.0 MBytes 462 Mbits/sec [ 4] 8.00-9.00 sec 56.5 MBytes 474 Mbits/sec [ 4] 9.00-10.00 sec 58.9 MBytes 492 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 570 MBytes 478 Mbits/sec sender [ 4] 0.00-10.00 sec 570 MBytes 478 Mbits/sec receiver iperf Done. </code></pre> <p>1Gbps 出てないが、まぁこんなもんだろう。</p> <h3 id="qdisc 制御 GUI コード"><a href="#qdisc+%E5%88%B6%E5%BE%A1+GUI+%E3%82%B3%E3%83%BC%E3%83%89">qdisc 制御 GUI コード</a></h3> <p>Raspberry Pi 上のブリッジを通過して通信が通るようになったので、お次は通過するパケットに遅延やパケロスを発生させるための UI を作る。</p> <p>UI 上でポチポチした値を基に、 <code>tc qdisc</code> コマンドを実行するような、単純な仕組みで良いだろう。<br /> Python と tkinter で適当に仕上げてみる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5">https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5</a><br /> <gist src="https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5.js"></gist></p> <p>試しに動かしてみた動画がこちら。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2021/01/pi-nw-emu-ping.mp4">https://aquasoftware.net/blog/wp-content/uploads/2021/01/pi-nw-emu-ping.mp4</a></p> <p>UI上で設定した値に応じて、 ping の遅延とパケロスが発生しているのが、一目瞭然だろう。</p> <p>遅延を 100ms (RTT 200ms) としたときに、先ほどと同じ組み合わせで iperf を動かしたところ、以下のようになった。</p> <pre><code>> .\iperf3.exe -c PC2 Connecting to host 192.168.1.222, port 5201 [ 4] local 192.168.1.111 port 59582 connected to 192.168.1.222 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.03 sec 256 KBytes 2.04 Mbits/sec [ 4] 1.03-2.03 sec 0.00 Bytes 0.00 bits/sec [ 4] 2.03-3.00 sec 512 KBytes 4.30 Mbits/sec [ 4] 3.00-4.00 sec 384 KBytes 3.14 Mbits/sec [ 4] 4.00-5.01 sec 640 KBytes 5.23 Mbits/sec [ 4] 5.01-6.01 sec 384 KBytes 3.14 Mbits/sec [ 4] 6.01-7.01 sec 512 KBytes 4.18 Mbits/sec [ 4] 7.01-8.01 sec 384 KBytes 3.14 Mbits/sec [ 4] 8.01-9.00 sec 640 KBytes 5.31 Mbits/sec [ 4] 9.00-10.00 sec 384 KBytes 3.14 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 4.00 MBytes 3.35 Mbits/sec sender [ 4] 0.00-10.00 sec 3.95 MBytes 3.31 Mbits/sec receiver iperf Done. </code></pre> <p>輻輳制御が働いて 3.35Mbps しか速度が出なくなっていることがわかる。</p> <p>…とまぁ、こんな感じで目的を達成することができた。</p> <h2 id="余談"><a href="#%E4%BD%99%E8%AB%87">余談</a></h2> <h3 id="Raspberry Pi に Raspberry Pi OS 以外の OS を入れる場合"><a href="#Raspberry+Pi+%E3%81%AB+Raspberry+Pi+OS+%E4%BB%A5%E5%A4%96%E3%81%AE+OS+%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B%E5%A0%B4%E5%90%88">Raspberry Pi に Raspberry Pi OS 以外の OS を入れる場合</a></h3> <p>Raspberry Pi OS では、標準だと sudo コマンドにパスワードが不要な設定が visudo にされている。<br /> 一方、 Ubuntu など他の多くのディストリビューションではそうなっていない。</p> <p>他の OS で動かしたい場合、 visudo で <code>/usr/sbin/tc</code> コマンドをパスワードなしで実行できるように設定しておこう。</p> <h3 id="OSOYOO のタッチスクリーン付き LCD について"><a href="#OSOYOO+%E3%81%AE%E3%82%BF%E3%83%83%E3%83%81%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E4%BB%98%E3%81%8D+LCD+%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">OSOYOO のタッチスクリーン付き LCD について</a></h3> <p>先ほど挙げた OSOYOO のタッチスクリーン付き LCD は、 この価格帯のものなので過度な期待は禁物ではあるものの、 少なくともこの用途にはコスパ抜群だった。</p> <p>クリアケース付きのもののケースは、正直このクオリティだと +1,000円 分に達していないレベルのものだが、 LCD ディスプレイにちょうど合うサイズだったので、払ってしまっても損はないと思う。<br /> ただし、 Raspberry Pi 4B には端子の穴の位置が合わないため、サイドのアクリルが取り付けられなかった。</p> <p>また、同梱されていた紙のマニュアルに書かれていたリンクでダウンロードしたドライバーが古かったらしく、 最新の Raspberry Pi OS に入れたら、 タッチ位置が 90° 回転して認識されるトラブルに遭遇した。<br /> 以下のオンラインマニュアルのリンク先の、最新(?) のドライバーを使うようにしたら、上記のタッチ位置の問題は解消されたので、参考まで。<br /> <a target="_blank" rel="nofollow noopener" href="http://osoyoo.com/ja/?p=4244">http://osoyoo.com/ja/?p=4244</a></p> <p>同梱されていた Raspberry Pi 4B 用の HDMI - microHDMI コネクターが壊れていたのだが、 サポートにメールしたら即返事が来て代替品送ってくれたので、好印象。<br /> 代替品が届くまでは、家にあった変換ケーブルで我慢。</p> <p>一方で、タッチパネルの「ドライバー」とやらが、インストールスクリプトの中身をよく見ると、 何故かカーネルごとゴッソリ置き換える仕組みになっている。<br /> HW のドライバーという時点で、提供元を信頼しないとどうしようもないのだが、カーネルごと置き換えられるのにはちょっとモニョる。</p> <p>2020年末現在、 Raspberry Pi OS の Linux カーネルは 5.4系 なのだが、 このドライバーでカーネルが置き換えられると、 Linux カーネルが 4.19系 に落ちる点は注意。<br /> とりあえず、 <code>2020-12-02-raspios-buster-armhf</code> にインストールした限りは、問題なく動いていそうではあるが。</p> <p>マニュアルにも書いてあるが、 Kernel を更新すると正常に動作しなくなる可能性があるので、 apt の更新大将から Kernel を除外すると良いようだ。<br /> このため、常用するマシンにはオススメしない。</p> advanceboy tag:crieit.net,2005:PublicArticle/16219 2020-11-16T12:18:58+09:00 2020-12-07T09:39:05+09:00 https://crieit.net/posts/Raspberry-Pi-Slack 【Raspberry Pi】インターホンが押されたらSlackへ通知する仕組みを作る <p><strong>本記事は2020/05/09に作成したものです。<br /> 最新の環境ではうまく動作しない可能性がありますのでご注意ください</strong>。</p> <p>ステイホーム中の運動といえば、我が家はNetflix見ながらのローラー台です。<br /> 今とても安全に運動できるのでホント助かっています。</p> <p><a href="https://crieit.now.sh/upload_images/cc69dec91313bd16b1f6f7e5013a4fb45fb1ef02da909.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cc69dec91313bd16b1f6f7e5013a4fb45fb1ef02da909.jpg?mw=700" alt="8ba6c0f698b5cb26b9930e9aee59013e.jpg" /></a></p> <p>ただ、これやっていると<strong>イヤホン</strong>していることもあってインターホンのチャイム音に全く気がつけないんですよね。。。このままでは、宅配業者を返してしまうこともあり大変申し訳ない。<br /> そこで、<strong>「インターフォンが押されたらSlackへ通知する仕組みを作ればいいじゃないか」</strong> となり、ラズパイとセンサーを組み合わせて作ってみました。<br /> これならチャリもがいていても、スマートウォッチの通知でバッチリ気がつきます。</p> <h1 id="どのように検知させるか?"><a href="#%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%A4%9C%E7%9F%A5%E3%81%95%E3%81%9B%E3%82%8B%E3%81%8B%EF%BC%9F">どのように検知させるか?</a></h1> <p>我が家はインターホンが押されると、親機のディスプレイが点灯します。</p> <p><a href="https://crieit.now.sh/upload_images/3d354d0859dc6dec757bd61f8e6f10e65fb1ef261334f.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3d354d0859dc6dec757bd61f8e6f10e65fb1ef261334f.jpg?mw=700" alt="01f835e39314ac81894316137738f118.jpg" /></a></p> <p>明るさの変化を検知できるフォトレジスタを使ったセンサーなら、簡単に検知できそうです。<br /> ネットで、<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/KKHMF-%E6%84%9F%E5%85%89%E6%80%A7%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-%E3%83%95%E3%82%A9%E3%83%88%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B/dp/B0759XWC3L?ref_=ast_bbp_dp">明るさの変化をデジタル出力するセンサー</a>を見つけたのでこれを使うことにしました。<br /> 3.3Vで駆動させると、暗くなると3.3V、明るくなると0Vになります。<br /> つまみは検知する明るさの調整もできます。安いのに素敵なセンサーです。</p> <h2 id="用意したもの"><a href="#%E7%94%A8%E6%84%8F%E3%81%97%E3%81%9F%E3%82%82%E3%81%AE">用意したもの</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/KKHMF-%E6%84%9F%E5%85%89%E6%80%A7%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-%E3%83%95%E3%82%A9%E3%83%88%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B/dp/B0759XWC3L?ref_=ast_bbp_dp">KKHMF 感光性センサーモジュール フォトレジスタモジュール Arduinoと互換</a></li> <li>Raspberry Pi 3 Model B+ (Raspbian 9.4 stretch)</li> <li>ジャンパーワイヤ</li> </ul> <h2 id="ラズパイとセンサーの接続"><a href="#%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4%E3%81%A8%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%81%AE%E6%8E%A5%E7%B6%9A">ラズパイとセンサーの接続</a></h2> <p><a href="https://crieit.now.sh/upload_images/dd1aca1d857ddebaac05b8d8f2ed7f3d5fb1ef3cd403e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/dd1aca1d857ddebaac05b8d8f2ed7f3d5fb1ef3cd403e.png?mw=700" alt="e22ed1030afb8045e3148a35867184ff.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/84edf7870105833c47e55e163f79adac5fb1ef5906cb4.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/84edf7870105833c47e55e163f79adac5fb1ef5906cb4.jpg?mw=700" alt="b805b31c8a8587b58cbacab1e04051f7.jpg" /></a></p> <h2 id="インターホン親機へセンサーを固定"><a href="#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%9B%E3%83%B3%E8%A6%AA%E6%A9%9F%E3%81%B8%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%82%92%E5%9B%BA%E5%AE%9A">インターホン親機へセンサーを固定</a></h2> <p><a href="https://crieit.now.sh/upload_images/56a67aa4082f8d37fd47431e6535e68a5fb1ef7756a8a.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/56a67aa4082f8d37fd47431e6535e68a5fb1ef7756a8a.jpg?mw=700" alt="48208a459bcda1c9cb7d1d5e613d1188.jpg" /></a><br /> 仮固定なので適当です。。。<br /> インターホンを押して、センサーがちゃんと検知するかつまみで調整をします。<br /> (このセンサーは検知すると基盤のLEDが点灯するので、調整がとても簡単!)</p> <h2 id="センサーが検知したらSlackへ通知するコード"><a href="#%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%81%8C%E6%A4%9C%E7%9F%A5%E3%81%97%E3%81%9F%E3%82%89Slack%E3%81%B8%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89">センサーが検知したらSlackへ通知するコード</a></h2> <p>Slackで「Incoming Webhook」の設定が済んでいることと、slackwebモジュールのインストールが完了していることを前提にしています<br /> ※現在は非推奨になっている「カスタムインテグレーション」で作成した「Incoming Webhook」で動作確認しています。</p> <h3 id="/home/pi/chime2slack.py"><a href="#%2Fhome%2Fpi%2Fchime2slack.py">/home/pi/chime2slack.py</a></h3> <pre><code class="python">import RPi.GPIO as GPIO from time import sleep import slackweb SENSOR = 4 GPIO.setwarnings(False) GPIO.cleanup() GPIO.setmode(GPIO.BCM) GPIO.setup(SENSOR, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) SLACK = slackweb.Slack(url="https://hooks.slack.com/services/xxxx/xxxx/xxxx") #Incoming Webhookのurlをここへ記述します while True: if GPIO.input(SENSOR) == GPIO.LOW: SLACK.notify(text="チャイムが鳴りました!") sleep(60) #連続で通知されないようにスリープを入れる else: pass sleep(0.01) </code></pre> <h3 id="Slack通知イメージ"><a href="#Slack%E9%80%9A%E7%9F%A5%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8">Slack通知イメージ</a></h3> <p><img src="https://s3.qrunch.io/8b088b6fe1043e2dad6ef341729720e5.png" alt="undefined.jpg" /></p> <h2 id="OS起動時にchime2slack.pyを実行させる"><a href="#OS%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%ABchime2slack.py%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B">OS起動時にchime2slack.pyを実行させる</a></h2> <p>OS起動時に自動実行すれば、都度実行させなくていいので運用がラクです</p> <h3 id="chime2slack.pyに実行権限を追加する"><a href="#chime2slack.py%E3%81%AB%E5%AE%9F%E8%A1%8C%E6%A8%A9%E9%99%90%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B">chime2slack.pyに実行権限を追加する</a></h3> <pre><code class="bash">$ chmod +x /home/pi/chime2slack.py </code></pre> <h2 id="rc.localの編集"><a href="#rc.local%E3%81%AE%E7%B7%A8%E9%9B%86">rc.localの編集</a></h2> <p>rc.localで自動起動させるやり方はうまく動作しないこともあるのでおすすめできませんが...</p> <pre><code class="bash">$ sudo vi /etc/rc.local </code></pre> <h3 id="rc.localの中身"><a href="#rc.local%E3%81%AE%E4%B8%AD%E8%BA%AB">rc.localの中身</a></h3> <pre><code class="bash">#!/bin/bash -e sudo -u pi /usr/bin/python3 /home/pi/chime2slack.py & exit 0 </code></pre> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <p>OSを再起動して、インターホンを押してSlackへ通知がきたらOKです!</p> <h2 id="所感"><a href="#%E6%89%80%E6%84%9F">所感</a></h2> <p>とてもイイです。安いセンサーだけど問題なく使えています。<br /> 欲を言えば、Echo showにも通知させたい。。。<br /> 最新型インターホンがある家は、わざわざこんなことしなくてもスマホ通知できると思いますが、<br /> 我が家のようなインターホン使ってて同じ悩みがある人は、簡単に実装できるのでオススメです。</p> arohajiro tag:crieit.net,2005:PublicArticle/16218 2020-11-16T11:07:19+09:00 2020-12-07T09:37:22+09:00 https://crieit.net/posts/Raspberry-Pi 【Raspberry Pi】モニターの色が緑ががって見辛いのをなんとかする <h3 id="事象"><a href="#%E4%BA%8B%E8%B1%A1">事象</a></h3> <p>Amazonで買った格安小型モニターですが、パソコンを接続する時は何も問題ないけど<br /> ラズパイに接続した時だけ奇妙の色合いになってしまう...<br /> <a href="https://crieit.now.sh/upload_images/528494baef37880c055975d0bd52b07d5fb1de3e300f6.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/528494baef37880c055975d0bd52b07d5fb1de3e300f6.jpg?mw=700" alt="6b89b3915f3a26efc103896e214690a1.jpg" /></a></p> <h3 id="この記事の手順でできること"><a href="#%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E6%89%8B%E9%A0%86%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%93%E3%81%A8">この記事の手順でできること</a></h3> <p>上記事象をラズパイのHDMIグループ設定をDMTモードに固定することで解消します</p> <h3 id="確認済み環境"><a href="#%E7%A2%BA%E8%AA%8D%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83">確認済み環境</a></h3> <ul> <li>Raspberry Pi 3 Model B+</li> <li>Amazonで買ったcocoper製の小型モニター (型番不詳)</li> <li>Raspbian 9.4 stretch (日本語環境)</li> </ul> <h3 id="DMTモードに固定する方法"><a href="#DMT%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AB%E5%9B%BA%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95">DMTモードに固定する方法</a></h3> <h4 id="1. /boot/config.txtを編集"><a href="#%EF%BC%91.%E3%80%80%2Fboot%2Fconfig.txt%E3%82%92%E7%B7%A8%E9%9B%86">1. /boot/config.txtを編集</a></h4> <p>nanoやvim等のテキストエディタで以下を追加するだけ</p> <pre><code>hdmi_group=2 </code></pre> <h4 id="2. 再起動"><a href="#%EF%BC%92.%E3%80%80%E5%86%8D%E8%B5%B7%E5%8B%95">2. 再起動</a></h4> <pre><code class="bash">$ sudo reboot </code></pre> <p>再起動後、画面の色が緑かからなければOK!<br /> (ブートの初期は緑ががっていますが、途中で変わります)</p> <p><a href="https://crieit.now.sh/upload_images/7bd1415fca73dc7dfa8f4960905e81445fb1de7273952.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7bd1415fca73dc7dfa8f4960905e81445fb1de7273952.jpg?mw=700" alt="13dd4a1b3e09a11a8cc259db88bba806.jpg" /></a></p> arohajiro tag:crieit.net,2005:PublicArticle/16217 2020-11-16T10:58:43+09:00 2021-01-15T12:02:41+09:00 https://crieit.net/posts/Raspberry-Pi-Raspberry-Pi-1 【Raspberry Pi】Raspberry Piをデジタルサイネージ風に使う その1 <h2 id="できること"><a href="#%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%93%E3%81%A8">できること</a></h2> <p>ラズパイを使って、PDFのスライドショー映像をモニターへリピート再生できます!<br /> 要は簡易的なデジタルサイネージですね<br /> 再生コンテンツはPowerPointで作成したスライドをPDFに変換すると簡単です。</p> <p>あくまで簡易的なので、スライドショーの再生にはラズパイの直接操作が必要です。<br /> コマンドで再生操作できる方法は、残念ながらまだ調べてないです。</p> <h3 id="動作イメージ"><a href="#%E5%8B%95%E4%BD%9C%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8">動作イメージ</a></h3> <p><a href="https://crieit.now.sh/upload_images/1714b4676d0501ff29b1908a480af2d95fb1dc56bf31a.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1714b4676d0501ff29b1908a480af2d95fb1dc56bf31a.gif?mw=700" alt="cac398213540a227586f69c708f4541d.gif" /></a></p> <h2 id="動作確認済み環境"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83">動作確認済み環境</a></h2> <ul> <li>Raspberry Pi 3 Model B+</li> <li>HDMIのモニター (ラズパイに給電可能なUSB端子があると最高)</li> <li>Raspbian 9.4 stretch (日本語環境)</li> <li>Okular 4:16.08.2-1</li> <li>XScreenSaver 5.36-1</li> </ul> <h3 id="1. PDFのスライドショーを行う準備"><a href="#1.+PDF%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E3%82%92%E8%A1%8C%E3%81%86%E6%BA%96%E5%82%99">1. PDFのスライドショーを行う準備</a></h3> <p>標準のPDFリーダーではスライドショー設定が見当たらなかったので「Okular」をインストールします</p> <h4 id="「Okular」のインストール"><a href="#%E3%80%8COkular%E3%80%8D%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">「Okular」のインストール</a></h4> <p>ターミナルからaptコマンドでインストール</p> <pre><code class="bash">$ sudo apt -y install okular </code></pre> <h4 id="「Okular」の設定"><a href="#%E3%80%8COkular%E3%80%8D%E3%81%AE%E8%A8%AD%E5%AE%9A">「Okular」の設定</a></h4> <p>PDFを7秒ごとに1ページ進め、最終ページの次は1ページ目に戻る設定を入れる</p> <ol> <li>「okular」を起動し、メニューから 「Settings」 -> 「Configure Okular」をクリック</li> <li>「Presentation」の「Navigation」を以下のように設定 <ul> <li>「Advance every」にチェック、「7seconds」にする</li> <li>「Loop after last page」にチェックして設定はおわり</li> </ul></li> </ol> <h3 id="2. スライドショー中にモニターを消さない"><a href="#2.+%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E4%B8%AD%E3%81%AB%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%92%E6%B6%88%E3%81%95%E3%81%AA%E3%81%84">2. スライドショー中にモニターを消さない</a></h3> <p>ラズパイの標準設定では、10分以上無操作だとスクリーンセーバーが起動してモニターがブラックアウトします。<br /> このままではデジタルサイネージとして使い物にならないのでスクリーンセーバーを無効化します。</p> <h4 id="「XScreenSaver」のインストール"><a href="#%E3%80%8CXScreenSaver%E3%80%8D%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">「XScreenSaver」のインストール</a></h4> <p>ターミナルからaptコマンドでインストール</p> <pre><code class="bash">$ sudo apt -y install xscreensaver </code></pre> <p>※インストール後、再起動しないとスクリーンセーバーの設定画面が起動しない</p> <h4 id="スクリーンセーバーの無効化"><a href="#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%BB%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E7%84%A1%E5%8A%B9%E5%8C%96">スクリーンセーバーの無効化</a></h4> <ol> <li>ラズパイのスタートメニューから、 「設定」 -> 「スクリーンセーバー」をクリック</li> <li>「表示モード」タブの「モード」を「セーバーを無効にする」を選択して設定はおわり</li> </ol> <h3 id="3. スライドショーを実行"><a href="#3.+%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E3%82%92%E5%AE%9F%E8%A1%8C">3. スライドショーを実行</a></h3> <p>事前に再生したいPDFファイルをラズパイに移動してください、あとは再生するだけです。<br /> ちなみに、スライドショー再生中にPDFファイルを更新すると、スライドショーの内容も自動で更新されます(個人的は結構重宝する機能?です)</p> <ol> <li>ファイルマネージャから再生するPDFを右クリックし、メニューから「Okular」を起動</li> <li>メニューから「View」 -> 「Presentation」をクリックして完了!</li> </ol> <p>※スライドショーをやめる場合は「Esc」キーを押す</p> <p><a href="https://crieit.net/posts/Raspberry-Pi-Raspberry-Pi-2-rclone">その2の記事</a> に続く。。。</p> arohajiro tag:crieit.net,2005:PublicArticle/16116 2020-10-06T09:13:35+09:00 2020-10-20T13:29:51+09:00 https://crieit.net/posts/Raspberry-Pi-Desktop-OS-for-PC-USB 【Raspberry Pi Desktop OS for PC】USBシリアルコンソールを使えるようにする <h2 id="実機環境"><a href="#%E5%AE%9F%E6%A9%9F%E7%92%B0%E5%A2%83">実機環境</a></h2> <ul> <li>マシン Acer Aspire One 722</li> <li>USBシリアルコンソール iBUFFALO BSUSRC06</li> <li>OS Debian Stretch with Raspberry Pi Desktop (November 2018)</li> </ul> <h3 id="USBシリアルコンソールがOSから認識されるか確認"><a href="#USB%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%8COS%E3%81%8B%E3%82%89%E8%AA%8D%E8%AD%98%E3%81%95%E3%82%8C%E3%82%8B%E3%81%8B%E7%A2%BA%E8%AA%8D">USBシリアルコンソールがOSから認識されるか確認</a></h3> <p>USBシリアルコンソールの認識状況をsyslogで確認するため、USBに接続する前にtail -fしておく</p> <pre><code class="bash">$ sudo tail -f /var/log/syslog </code></pre> <p>以下ログではttyUSB0として認識されてます</p> <pre><code>Mar 29 13:29:15 raspberry kernel: [30527.454485] ftdi_sio 3-1:1.0: FTDI USB Serial Device converter detected Mar 29 13:29:15 raspberry kernel: [30527.454607] usb 3-1: Detected FT232BM Mar 29 13:29:15 raspberry kernel: [30527.459503] usb 3-1: FTDI USB Serial Device converter now attached to ttyUSB0 </code></pre> <h3 id="gtktermインストール"><a href="#gtkterm%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">gtktermインストール</a></h3> <p>デスクトップ画面で使えるgtktermをインストール</p> <pre><code class="bash">$ sudo apt install gtkterm </code></pre> <h3 id="gtktermの起動及び設定"><a href="#gtkterm%E3%81%AE%E8%B5%B7%E5%8B%95%E5%8F%8A%E3%81%B3%E8%A8%AD%E5%AE%9A">gtktermの起動及び設定</a></h3> <ul> <li>[ラズパイメニュー] -> [アクセサリ] にある 「serial port terminal」を起動すると立ち上がる</li> <li>シリアルポートの設定は gtktermのウインドウにある [Configuration] -> [Port] で行う <ul> <li>USBシリアルを使う場合はsyslogで確認したデバイスファイル名を選択(今回ならttyUSB0)</li> </ul></li> </ul> <p>シリアルコンソールを繋いだルータを起動してgtktermにログが出ればOK</p> arohajiro tag:crieit.net,2005:PublicArticle/16042 2020-09-01T00:07:27+09:00 2020-09-01T02:54:31+09:00 https://crieit.net/posts/Raspberry-Pi-Ubuntu-SSH-A-to-B Raspberry Pi に Ubuntu を入れて SSH でログインするまでの A to B <p>何番煎じかわからないが、 Raspberry Pi (以下、 RasPi) に Ubuntu を入れる手順についてまとめてみようと思う。</p> <p>Ubuntu 公式の <a target="_blank" rel="nofollow noopener" href="https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi">How to install Ubuntu on your Raspberry Pi</a> チュートリアルは充実しているし、 単にインストールして動かすだけなら、既にある記事でも十分だろうとは思う。<br /> しかし、初回セットアップ時の細かいカスタマイズについて書かれているものがあまり見当たらなかったので、この記事ではそれについて補足しながらまとめていく。</p> <p>先に断っておくが、 cloud-init による IaC の話が中心になる。</p> <h2 id="TL;DR"><a href="#TL%3BDR">TL;DR</a></h2> <ul> <li>焼いた SD を RasPi に挿す<strong>前</strong>にブートプロセスの設定を書き換える</li> <li>cloud-init の挙動を理解しろ</li> <li>モニター無し & 無線LAN Only だと、工夫がいる</li> <li>ARP リクエストのブロードキャストが届かないと苦労する</li> </ul> <h2 id="きっかけ"><a href="#%E3%81%8D%E3%81%A3%E3%81%8B%E3%81%91">きっかけ</a></h2> <p>完全に私事だが、 おしごとで Linux 使うことが増えてきて、 WSL (or WSL2) や仮想マシン上の知識だけではなかなか難しい、ネットワーク回りの知識が不足してきた。<br /> そこで、勉強がてら何らかの物理的な Linux マシンが欲しかった。</p> <p>中古の x86 ラップトップに Linux を入れるのでも良かったのだが、 それだと Linux 向けの無線やネットワーク回りのドライバーが揃っているか確認するのが難しい。<br /> そこで、様々な Linux ディストリビューションが公式でサポートされ、 I/O も充実していて、 コスパの高い Raspberry Pi 4 B+ をチョイス。</p> <p>これまで、 RasPi 自体は所持していたのだが、 電子工作目的であったことから Raspberry Pi OS (旧 Raspbian) しか入れていなかった。<br /> より Linux サーバーらしい使い方も試してみたいと言うことから、今回は Ubuntu をいれることした。</p> <p>いざ、セットアップはじめようとして、致命的な問題に気づく。<br /> <strong>micro-HDMI のケーブルを持っていないと言うことに…</strong></p> <p>ということで、 なんとかセットアップを工夫して、 <strong>モニターが無くても一通り設定して ssh できる</strong> ところまで持って行くことを目標にする。</p> <h2 id="準備"><a href="#%E6%BA%96%E5%82%99">準備</a></h2> <p>用意するものは以下の通り。</p> <ul> <li>Raspberry Pi 2 または 3 または 4</li> <li>8GB 以上の microSD カード</li> <li>misroSD を書き込める PC (Win, Linux, mac)</li> <li>インターネットに繋がる Wi-Fi または イーサネットケーブル</li> </ul> <p>RasPi 無印 や Zero など、 SoC (CPU) が ARMv6 のものは、 Ubuntu ではサポートされていない。</p> <p>microSD カードは、 IOPS が速いものの方が、後々うれしいだろう。<br /> SD カードの規格で言えば、 アプリケーションパフォーマンスクラス A1 や A2 に対応しているものが良いというコトなのだろうが、正直モデル差やロット差が激しすぎるので、実際買ってみて IPOS が早いかどうか試してみるしかないと思う。</p> <p>以下のものも有れば望ましいが、今回の手順ではなくても大丈夫。</p> <ul> <li>HDMI (RasPi 4 の場合は micro-HDMI) で繋がるモニター</li> <li>RasPi 繋げる USB キーボード</li> </ul> <h2 id="ブータブル SD の作成"><a href="#%E3%83%96%E3%83%BC%E3%82%BF%E3%83%96%E3%83%AB+SD+%E3%81%AE%E4%BD%9C%E6%88%90">ブータブル SD の作成</a></h2> <p>まず、使用する Ubuntu の OS イメージを準備しよう。</p> <p>2020年8月時点では、 20.04 LTS と 18.04 LTS に対して、それぞれ 32bit版 と 64bit版 が存在する。</p> <p>特に理由が無ければ、 20.04 LTS の 64bit 版で良いだろう。<br /> 但し、 512MiB しか RAM がない RasPi 3A+ では、 64bit OS だと ssh でアクセスするだけで Out of Memory してしまうので、 32bit にすることをオススメする。<br /> また、 RasPi 2 の CPU は 32bit 版なので、 32bit OS しか選べない。</p> <p>microSD への書き込みは、 主に 以下の 2種類 の方法がある。<br /> どちらか好きな方でどうぞ。</p> <p>メモ:</p> <pre><code>以前は NOOBS という、 RasPi を起動後に OS 選択させてインストールさせるツールも存在したが、今回は触れない。 詳しくはググってほしい。 </code></pre> <h3 id="1. イメージファイルをダウンロードして 任意のツールで焼き込む"><a href="#1.+%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%A6+%E4%BB%BB%E6%84%8F%E3%81%AE%E3%83%84%E3%83%BC%E3%83%AB%E3%81%A7%E7%84%BC%E3%81%8D%E8%BE%BC%E3%82%80">1. イメージファイルをダウンロードして 任意のツールで焼き込む</a></h3> <p><a href="https://crieit.now.sh/upload_images/cf06274a6f0865c95189a30c93ffa1195f4d1191446db.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cf06274a6f0865c95189a30c93ffa1195f4d1191446db.png?mw=700" alt="raspi-ubuntu-a-to-b-00.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://ubuntu.com/download/raspberry-pi">Install Ubuntu Server on a Raspberry Pi 2, 3 or 4</a> のページからダウンロードしたイメージファイルを、任意のツールで microSD に焼く方法。</p> <p>個人的には、 <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/etcher/">balenaEtcher</a> を使って焼くのが、以下の理由でオススメ。</p> <ul> <li>.gz, .xz, zip などで圧縮された状態のイメージをそのまま焼ける <ul> <li>オンザフライで解凍しながら焼かれるので、あらかじめ展開しておく必要が無い</li> <li>... と思っていたけど、最近のバージョンでは一旦一時ファイルに展開されてから焼かれるっぽい。 それでも早いけど。</li> </ul></li> <li>Portable 版がある (インストール不要)</li> </ul> <h3 id="2. Raspberry Pi Imager を使う"><a href="#2.+Raspberry+Pi+Imager+%E3%82%92%E4%BD%BF%E3%81%86">2. Raspberry Pi Imager を使う</a></h3> <p><a href="https://crieit.now.sh/upload_images/19226279f917418413a8da2657fee0ee5f4d11a93a8bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/19226279f917418413a8da2657fee0ee5f4d11a93a8bc.png?mw=700" alt="raspi-ubuntu-a-to-b-02.png" /></a><br /> Raspberry Pi 財団公式サイトの <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/downloads/">Raspberry Pi Downloadsi</a> ページからダウンロードできる、 Raspberry Pi Imager を使って、 OS のイメージをダウンロードしながら microSD に焼く方法。</p> <p>Raspberry Pi Imager をインストールして起動すると、 インストールしたい OS を尋ねられるので、 ここで Ubuntu の任意のバージョンを選択する。</p> <p>ダウンロードしながらそのまま焼き込むため、本来なら (1) よりも早くてオススメのハズ…<br /> …なのだが、少なくとも私が試した限り、 (1) のほうがずっと早いんだよねぇ。。。</p> <p>OS イメージを DL元 が違って、ダウンロード速度がネックになって遅くなっているのかな…<br /> あまり深く調べてないけど。</p> <h2 id="system-boot パーティション内の cloud-init 等の設定を書き換える"><a href="#system-boot+%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E5%86%85%E3%81%AE+cloud-init+%E7%AD%89%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%8B">system-boot パーティション内の cloud-init 等の設定を書き換える</a></h2> <p>作成した micorSD を早速 RasPi に挿す <strong>…前に</strong> 、 初回セットアップ設定の書き換えを行う。</p> <p>一度書き込んだ microSD を再び PC に挿すと、 <code>"system-boot"</code> という 250MB 位の FAT32 パーティションが開けるはずだ。</p> <p>このパーティション直下にある <code>README</code> というファイルを開くと、このパーティションに存在するファイルの概要が簡単に書いてある。</p> <pre><code class="text">An overview of the files on the /boot/firmware partition (the 1st partition on the SD card) used by the Ubuntu boot process (roughly in order) is as follows: * bootcode.bin - this is the second stage bootloader loaded by all pis with the exception of the pi4 (where this is replaced by flash memory) * config.txt - the first configuration file read by the boot process * syscfg.txt - the file in which system modified configuration will be placed, included by config.txt * usercfg.txt - the file in which user modified configuration should be placed, included by config.txt * start*.elf - the third stage bootloader, which handles device-tree modification and which loads... * uboot*.bin - various u-boot binaries for different pi platforms; these are launched as the "kernel" by config.txt * boot.scr - the boot script executed by uboot*.bin which in turn loads... * vmlinuz - the Linux kernel, executed by boot.scr * initrd.img - the initramfs, executed by boot.scr * meta-data - meta-data for cloud-init; usually just contains the instance id * network-config - network configuration for cloud-init; edit this to set up wifi access points and other networking settings * user-data - user-data for cloud-init; edit this to configure initial users, SSH keys, packages, etc. </code></pre> <p>このパーティションには、 Raspberry Pi の BIOS の変わりとなる <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/documentation/configuration/config-txt/">config.txt, bootcode.bin, start.elf</a> と言った構成ファイルや、 ブートコード、 そして cloud-init の構成ファイルが入っている。</p> <p>このうち <strong>cloud-init</strong> というのは、 Infrastructure as Code (IaC) の一種だ。 その名の通り、 AWS 等のクラウド上の仮想マシンの初期設定を得意としている。<br /> 校正用の設定ファイル (YAML) を使って設定内容を記述することで、 クラウドやディストリビューションの違いをある程度吸収して初期設定を記述することができる。<br /> OS のイメージ内に予め cloud-init のサービス(デーモン) が組み込まれており、 OS の起動時に各クラウドのサービスの UI 経由で設定ファイルを読み取って、 主に初回起動時に初期設定処理が走る… というのが主な仕組みとなっている。</p> <p>RaspPi 用の Ubuntu Server イメージでは、この cloud-init 用の設定ファイルの取得元が上記の <code>system-boot</code> パーティションとなっている。<br /> イメージ組み込みの定義と <code>system-boot</code> パーティション内の定義を組み合わせて、 初期設定が実行される。</p> <p>例えば、 このイメージを使ってそのまま Ubuntu を起動すると、 "ubuntu" という ログイン ID に "ubuntu" というパスワードが設定され、 SSH のパスワード認証が有効になった状態で起動している。<br /> このうち、 "ubuntu" というユーザー名と SSH サーバーの起動は、 OS 組み込みの <code>/etc/cloud/cloud.cfg</code> の定義によるもの。<br /> そして、 "ubuntu" というパスワードの設定と、 SSH のパスワード認証の有効化は、 <code>system-boot</code> パーティションの <code>user-data</code> ファイル内の以下の定義によるものだ。</p> <pre><code class="yaml">#cloud-config chpasswd: expire: true list: - ubuntu:ubuntu ssh_pwauth: true </code></pre> <p>とうことで、 遠隔から SSH ログインできるように、 こららのファイルを順に書き換えていこう。</p> <h3 id="cloud-init の network-config"><a href="#cloud-init+%E3%81%AE+network-config">cloud-init の network-config</a></h3> <p>network-config ファイルには、 以下の 2つ の大きな役割がある。</p> <ul> <li>cloud-init 初期設定実行前にデバイスをネットワークにつなぐ</li> <li>netplan の <code>/etc/netplan/50-cloud-init.yaml</code> にファイルの内容を転記する</li> </ul> <p>『何だ、同じことじゃないか』 と思われるかも知れないが、この二つは システムに適用されるタイミング と言う点で大きく異なる。</p> <p>前者は、 cloud-init サービス の起動直後に、 cloud-init の通信を行うためにシステムに適用される。<br /> 一方後者は、後者は内容をファイルにコピーするだけである。</p> <p>cloud-init サービスによって netplan の <code>50-cloud-init.yaml</code> が書き換わるのは、ネットワークサービスの起動より後になる (systemd の <code>/usr/lib/systemd/system/cloud-init.service</code> の設定を参照)。<br /> このため、システムやサービスが再起動されるか、能動的に netplan apply しないと、 <code>50-cloud-init.yaml</code> の内容は適用されない。</p> <p>そしてもう一つ重要なのが、以下の一文。</p> <p><a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html#network-config-v2">Networking Config Version 2 — cloud-init 20.3 documentation</a></p> <blockquote> <p>Cloud-init does not current support wifis type that is present in native netplan.</p> </blockquote> <p>そう。<br /> 前者では、 Wi-Fi の設定が無視されるのだ。</p> <p>すなわちこれは、 有線LAN が繋がっていない場合、 ファイルの更新や apt パッケージの取得などのインターネットに繋ぐような処理は、初回ブート時の cloud-init では全くできないことを意味する。<br /> 幸いにも、 Ubuntu イメージ組み込みの cloud-init の初期設定の内容は、ネットワークに繋がっていなくても処理が完走できる。</p> <p>cloud-init の元々の用途を考えれば、 Wi-Fi が設定できる必要性はないだろうし、 仕方が無いことなのかも知れないが……</p> <p>このファイルに Wi-Fi の設定を記載しただけでは、 初回起動時には Wi-Fi が有効にならないことは覚えておこう。<br /> 後の手順に関係してくる。</p> <p>とりあえず、 netplan の設定に Wi-Fi アクセスポイントの情報は書いておきたいので、 <code>network-config</code> は以下のように書き換える。<br /> SSID やパスワードは自分の環境のものに置き換えて書いてくれ。</p> <pre><code class="diff">--- network-config.org +++ network-config @@ -11,15 +11,15 @@ ethernets: eth0: dhcp4: true optional: true -#wifis: -# wlan0: -# dhcp4: true -# optional: true -# access-points: -# myhomewifi: -# password: "S3kr1t" +wifis: + wlan0: + dhcp4: true + optional: true + access-points: + "SSID-of-myhomewifi": + password: "password-of-myhomewifi" # myworkwifi: # password: "correct battery horse staple" # workssid: # auth: </code></pre> <h3 id="cloud-init の user-data"><a href="#cloud-init+%E3%81%AE+user-data">cloud-init の user-data</a></h3> <p>cloud-init 書き換えのメインとなる user-data。<br /> これは、 <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/format.html#cloud-config-data">Cloud Config Data</a> の内容を記述する YAML 形式のファイルだ。<br /> 基本的には、 OS 組み込みの <code>/etc/cloud/cloud.cfg</code> の値を上書きしたり、 <code>cloud.cfg</code> で読み込まれた <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/modules.html">Modules</a> の設定を記述していく。</p> <p>書き換え部分が長いので、3カ所に分けて説明していく。</p> <pre><code class="diff">--- user-data.org +++ user-data @@ -14,12 +14,22 @@ # expire user passwords chpasswd: expire: true list: - - ubuntu:ubuntu + - newusername:ubuntu + +# Override the default user name defined in cloud.cfg +system_info: + default_user: + name: newusername # Enable password authentication with the SSH daemon -ssh_pwauth: true +ssh_pwauth: false +ssh_authorized_keys: +- ssh-rsa AAAA<中略>== rsa-key-of-user1 + +# locale and timezone +timezone: Asia/Tokyo ## On first boot, use ssh-import-id to give the specific users SSH access to ## the default user #ssh_import_id: </code></pre> <p>既に上でも触れたが、 OS 組み込みの <code>cloud.cfg</code> の定義によって、 "ubuntu" というユーザーが作成されている。<br /> しかし、 既知のユーザー名をそのまま使うのはセキュリティ的にも若干不安があるし、 作成後のユーザー名を書き換えるのは若干面倒なので、作成されるデフォルトのユーザー名自体を、他の名前に書き換えてしまおう。<br /> <code>system_info.default_user</code> で、作成されるユーザ名を変更できる。<br /> また、 <code>chpasswd</code> によるパスワード書き換えの対象となるユーザ名も変更しておこう。</p> <p><code>ssh_pwauth</code> で、 ssh のパスワード認証が有効になっているので、 コレは切ってしまいつつ、<br /> 代わりに、 <code>ssh_authorized_keys[*]</code> リストに公開鍵を登録する。<br /> これで安全に ssh できるようになった。恵dc</p> <p>ついでにタイムゾーンも JST (Asia/Tokyo) に書き換えておこう。</p> <pre><code class="diff">--- user-data.org +++ user-data @@ -53,19 +63,20 @@ #- pastebinit #- [libpython2.7, 2.7.3-0ubuntu3.1] ## Write arbitrary files to the file-system (including binaries!) -#write_files: -#- path: /etc/default/keyboard -# content: | -# # KEYBOARD configuration file -# # Consult the keyboard(5) manual page. -# XKBMODEL="pc105" -# XKBLAYOUT="gb" -# XKBVARIANT="" -# XKBOPTIONS="ctrl: nocaps" -# permissions: '0644' -# owner: root:root +write_files: +- path: /etc/default/keyboard + content: | + # KEYBOARD configuration file + # Consult the keyboard(5) manual page. + XKBMODEL="pc105" + XKBLAYOUT="jp" + XKBVARIANT="" + XKBOPTIONS="" + permissions: '0644' + owner: root:root +- path: /etc/cloud/cloud-init.disabled #- encoding: gzip # path: /usr/bin/hello # content: !!binary | # H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA= </code></pre> <p>お次は、ファイルの作成。</p> <p>日本語キーボードを認識しないと面倒なので、 <code>/etc/default/keyboard</code> を書き換えて日本語キーレイアウトを認識させる。<br /> 但し、 Ubuntu Server では、このファイルを書き換えただけだとキーボードレイアウトの変更が有効にならないので、後述の <code>runcmd</code> で <code>dpkg-reconfigure</code> コマンドを対話無しのオプションをつけて実行しておく。</p> <p>cloud-init の設定の大半は、 初回ブート時にただ一度だけ実行されるのだが、 cloud-init サービス自体は基本的に毎回常に起動して、サービスとして常駐しっぱなしになっている。<br /> <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/modules.html">Modules</a> で、 <code>Module frequency: per always</code> となっているモジュールの実行などは、ブートする度に毎回実行される。<br /> そうすると、場合によっては cloud-init の実行ログがログイン画面を覆ってしまうことが毎回の起動毎に発生して鬱陶しい。<br /> このため、 <code>/etc/cloud/cloud-init.disabled</code> という <a target="_blank" rel="nofollow noopener" href="https://cloudinit.readthedocs.io/en/latest/topics/boot.html?highlight=%22cloud-init.disabled%22#generator">空ファイルを作成しておく</a> ことで、 次回以降の起動時に cloud-init を無効にしておく。</p> <pre><code class="diff">--- user-data.org +++ user-data @@ -72,8 +83,19 @@ # owner: root:root # permissions: '0755' ## Run arbitrary commands at rc.local like time -#runcmd: +runcmd: +# apply keyboard configration +- [ dpkg-reconfigure, -f, noninteractive, keyboard-configuration ] +# apply netplan config defined on 'network-config' +- [ netplan, apply ] +# after wlan0 is connected, write the arp entry to target machine on background job +- [ nohup, sh, -c, 'sleep 30; ping 192.168.0.2 &' ] #- [ ls, -l, / ] #- [ sh, -xc, "echo $(date) ': hello world!'" ] #- [ wget, "http://ubuntu.com", -O, /run/mydir/index.html ] + +# Restart 2 minutes after running all config modules (for apply keyboard configration) +power_state: + delay: '+2' + mode: reboot </code></pre> <p>最後に、任意のコマンドの実行。</p> <p>最初の <code>dpkg-reconfigure</code> は、 <code>keyboard</code> の書き換えを反映させるため。</p> <p><code>[ netplan, apply ]</code> のコマンドで初めて、 <code>network-config</code> で設定した Wi-Fi 設定が有効になる。</p> <p>最後の <code>[ nohup, sh, -c, 'sleep 30; ping 192.168.0.2 &' ]</code> は説明が難しいのだが、これは仮に ssh でゲストの IP アドレスが <code>192.168.0.2</code> であると仮定して、そこへ向かって Ping を打っている。<br /> 何故そのようなことをしているかというと、 ゲストPC から RaspPi の IP アドレスを ARP コマンドで確実に調べられるようにするためだ。</p> <p>RasPi に繋げるモニターがないことを前提とすると、 SSH するために DHCP によって RasPi に割り当てられた IP アドレスをどうやって調べるのか、と言う問題に直面する。</p> <p><a target="_blank" rel="nofollow noopener" href="https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#4-boot-ubuntu-server">How to install Ubuntu on your Raspberry Pi #4</a> に書かれているように、 RasPi の MAC アドレスの先頭 24bit は b8-27-eb (Pi 2~3) もしくは dc-a6-32 (Pi 4) と決まっている。<br /> 通常、 RasPi がオンラインになったときに、 ARPリクエストがブロードキャストされるため、 同一ネットワーク内の PC の ARP テーブルに RasPi のレコードが追加され、 以下のような arp コマンドで対象の IP アドレスを調べることができるようになる。。。 <strong>多くの場合は。</strong></p> <pre><code class="powershell">while(1) { arp -a | ?{ $_ -match 'dc-a6-32' }; Start-Sleep -Seconds 1} </code></pre> <p>ところが、 RasPi が Wi-Fi で繋いでいるのがルーターだったりすると、 ルーターが気を利かせて、 同じ サブネット内であっても ARPリクエストを代替して投げてしまい、 同じサブネットの端末全員の ARP テーブルには、 RasPi の MAC アドレスのレコードが記録されないことがある。</p> <p>そこで、 RasPi 側から SSH のアクセス元となる PC を指定して ping を投げることで、 その PC の ARP テーブルに確実に RasPi が載るようにしている。</p> <p>ちなみに、 30秒 sleep しているのは、 <code>netplan apply</code> した直後はまだ Wi-Fi に繋がっていないことが多いためだ。</p> <p>そして最後に、 cloud-init の停止や タイムゾーンの変更を確実に反映するため、 <code>power_state</code> で再起動させている。</p> <h2 id="RasPi の config.txt"><a href="#RasPi+%E3%81%AE+config.txt">RasPi の config.txt</a></h2> <p>cloud-init とは関係ないが、 必要があれば <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/documentation/configuration/config-txt/">config.txt</a> の構成ファイル書き換えてしまおう。</p> <p>例えば、 HDMI の解像度が一般的でなかった場合や、 端末とのネゴシエーションがヘタクソで適切な解像度で表示できない場合などは、 このファイルで HDMI の解像度を指定してやる必要がある。</p> <p>参考:<br /> * <a target="_blank" rel="nofollow noopener" href="https://qiita.com/god19/items/da8ce82b93b36dd5489d">Raspberry Pi 4B 画面解像度設定(TV出力版) - Qiita</a><br /> * <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/documentation/configuration/config-txt/video.md">Video options in config.txt - Raspberry Pi Documentation</a></p> <p>但し、 <code>config.txt</code> には、</p> <pre><code class="conf"># Please DO NOT modify this file; if you need to modify the boot config, the # &quot;usercfg.txt&quot; file is the place to include user changes. </code></pre> <p>って書いてあるので、 書き換えるなら <code>config.txt</code> ではなく <code>usercfg.txt</code> にしておくと良い。</p> <pre><code class="diff">--- usercfg.txt.org +++ usercfg.txt @@ -1,3 +1,9 @@ # Place "config.txt" changes (dtparam, dtoverlay, disable_overscan, etc.) in # this file. Please refer to the README file for a description of the various # configuration files on the boot partition. + +framebuffer_width=1024 +framebuffer_height=600 +hdmi_group=2 +hdmi_mode=87 +hdmi_cvt=1024 600 60 1 0 0 0 </code></pre> <h2 id="起動する"><a href="#%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B">起動する</a></h2> <p>こんな感じで一通りファイルを書き換えたと、 RasPi に microSD をさして起動すると、初回ブート時の設定を適用しながら起動してくれる。</p> <p>cloud-init の処理が終わらなくても、 ログイン画面には進み、 その後も cloud-init のサービスは稼働し続ける。<br /> このため、 最初の起動でログイン可能になったとしてもログインせず、 全ての処理が終わって一度再起動されるのをおとなしく待つ方が良い。</p> <p>RasPi 3A+ の場合、全ての処理が終わるのに5分以上ったので、気長に待つようにしよう。</p> <p>前述の arp で RasPi の IPアドレスを調べて、そこに対して SSH できるようになっていれば、とりあえずは完成だ。</p> <p>cloud-init についてもう少し掘り下げて説明しようと思ったのだが、記事が長くなってしまったので、次回の更新に回す。</p> advanceboy tag:crieit.net,2005:PublicArticle/15760 2020-03-11T20:21:24+09:00 2020-03-11T20:21:24+09:00 https://crieit.net/posts/RaspberryPi-Bluetooth RaspberryPi Bluetoothレシーバー(スピーカー)構築について <p>この間 "balenaOSを用いて簡単にラズパイBluetoothレシーバを構築する" という記事を書いた。改めてこの記事について深堀りしたいと思う。</p> <p>この間の記事<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/ksmndevelop/items/39bbb650ef21798f89fb">https://qiita.com/ksmndevelop/items/39bbb650ef21798f89fb</a></p> <h1 id="そもそもbalenaOSとは"><a href="#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82balenaOS%E3%81%A8%E3%81%AF">そもそもbalenaOSとは</a></h1> <p>balenaCloudについてはここでは触れない。<br /> 検索しても日本語のページが少ないため一応簡単に説明しておく。</p> <p>balenaOS公式ページに書いてある。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/os/">https://www.balena.io/os/</a></p> <blockquote> <p>"最新のソフトウェア開発ツールを接続ハードウェアの世界にもたらすプラットフォームであるbalenaCloudの構築を目指して、2013年にDockerをARMチップに移植することから始めました。"</p> </blockquote> <p>と記載どおりDockerをARMに移植するために始めたとのこと。<br /> 要するにほぼDockerコンテナだけを動かすOSと言えるだろう。<br /> Dockerだと簡単にIoT環境構築できるためとても汎用的。</p> <p>公式からの画像<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/c5115c44-d777-44b9-3c1c-442fac157cf2.png" alt="[email protected]" /></p> <h1 id="balenaOSの利点"><a href="#balenaOS%E3%81%AE%E5%88%A9%E7%82%B9">balenaOSの利点</a></h1> <ul> <li>Dockerコンテナをほぼ直接動かしているため動作が軽快(X Window などGUIではなくCUI環境のためOSが軽い)</li> <li>ラズパイのようなシングルボードコンピュータにほぼ対応していおり同じ環境が簡単につくれる</li> <li>balena Cloud上でコードデプロイするためネット環境さえあればどこでも遠隔操作が簡単に可能</li> <li>balena Cloud上でデバイスの状態をGUIで監視、操作するため複数のデバイスを誰でも簡単に管理操作ができる。</li> <li>つまりIoT環境がとても簡単に構築できるということ。</li> </ul> <h1 id="balenaOSでできること"><a href="#balenaOS%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%93%E3%81%A8">balenaOSでできること</a></h1> <p>ラズパイでBluetoothレシーバを構築したように他にも様々なプロジェクトを構築できる。</p> <p>・WEBフレーム<br />  YouTubeやGoogleフォトに保存した画像等をディスプレイに表示する。"balena DASH"というプロジェクトコードを利用する。<br /> 30分でつくれると書いてある。。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/blog/make-a-web-frame-with-raspberry-pi-in-30-minutes/">https://www.balena.io/blog/make-a-web-frame-with-raspberry-pi-in-30-minutes/</a><br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/1f463e5a-9517-420b-2fcc-c3dcafd34d78.png" alt="image.png" /></p> <p>・エアーモニター<br />  室内環境をセンサーを用いて監視できるようにする。"balena Sense"というプロジェクトコードを利用する。<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/97734aaa-2529-d860-f40a-d6b8dfdc35ab.png" alt="image.png" /></p> <p>この他たくさん構築出来るようなのでbalena blogを参照してほしい。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/blog/">https://www.balena.io/blog/</a></p> <h1 id="今回構築したラズパイBluetoothレシーバの詳細"><a href="#%E4%BB%8A%E5%9B%9E%E6%A7%8B%E7%AF%89%E3%81%97%E3%81%9F%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4Bluetooth%E3%83%AC%E3%82%B7%E3%83%BC%E3%83%90%E3%81%AE%E8%A9%B3%E7%B4%B0">今回構築したラズパイBluetoothレシーバの詳細</a></h1> <p>構築方法しか書かなかったためここでコードについて少し記述する。<br /> balana Soundのコード(Github)<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/balenalabs/balena-sound/">https://github.com/balenalabs/balena-sound/</a></p> <p>Bluetoothについてのコードを見てみる。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/balenalabs/balena-sound/blob/master/bluetooth-audio/Dockerfile.template">https://github.com/balenalabs/balena-sound/blob/master/bluetooth-audio/Dockerfile.template</a><br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/1d08715d-0a5c-dfc0-0ab7-d1c38e1da27d.png" alt="image.png" /><br /> <code>RUN install_packages</code> の行をみると <code>alsa-utils</code> <code>bluealsa</code> <code>bluez</code> <code>python-project</code> <code>python-dbus</code> <code>python-gpiozero</code> <code>mplayer</code>を利用していることがわかる。<br /> ラズパイで一般的にraspbian上でレシーバー化するにはbluezを使うのだが、balena Soundもやはりbluezを利用していた。<br /> raspberianでコマンドをそれぞれ打ってインストールしてやるより簡単ではあるが、ほぼ環境は同じと言えよう。</p> <p>次にAirplayのコードを見てみる。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/balenalabs/balena-sound/blob/master/airplay/Dockerfile.template">https://github.com/balenalabs/balena-sound/blob/master/airplay/Dockerfile.template</a><br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/cc83533b-4bd2-8415-3a83-58afe96a3bc8.png" alt="image.png" /><br /> これもラズパイで一般的にAirplayを利用する際に使われる<code>shairport-sync</code>が使われている。</p> <p>さらにSpotifyConnectのコード。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/balenalabs/balena-sound/blob/master/spotify/Dockerfile.template">https://github.com/balenalabs/balena-sound/blob/master/spotify/Dockerfile.template</a><br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/d9437c5a-339b-d2f6-ffa1-c82d9fa67648.png" alt="image.png" /><br /> どうやら"raspotify"が使われているらしい。<br /> raspbianでも構築可能。(もともとそっち用)<br /> <a target="_blank" rel="nofollow noopener" href="https://dtcooper.github.io/raspotify/">https://dtcooper.github.io/raspotify/</a></p> <p>言わずもがなであるがraspbianで構築した方法とほぼ一緒だった。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>今回は以前の投稿の詳細として追記した。raspbianでも同じような環境を作れると思うがbalenaOSでとても簡単にできることがより一層理解できたと思う。</p> かすみん@Crieit出張版 tag:crieit.net,2005:PublicArticle/15759 2020-03-11T20:17:58+09:00 2020-03-11T20:17:58+09:00 https://crieit.net/posts/Kodi-YouTube-Plugin-2020-02 Kodi YouTube Plugin が開けない問題 (2020-02) <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>ラズパイ4B (RAM4G) にてLibreELEC運用で快適動画生活を送って(?)いる。<br /> ところが最近、YouTubeのプラグインがエラーにより開けなくなった。</p> <h1 id="とりあえず環境"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E7%92%B0%E5%A2%83">とりあえず環境</a></h1> <p>・Raspberry Pi 4B (RAM 4G)<br /> ・LibreELEC 9.2.0 (Kodi v18.5)</p> <p>これでYouTube、アマプラを視聴している。快適。</p> <h1 id="エラーログ"><a href="#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%AD%E3%82%B0">エラーログ</a></h1> <p>こんなエラーがトースト</p> <pre><code>YouTube LoginException: [401] deleted_client The OAuth client was deleted. </code></pre> <p>401エラー。<br /> どうやら、OAuth認証が無いよーというエラー。<br /> てかAPIキーが消された。<br /> エラーで大体対処法が分かったのでAPI発行すればオッケーだと思った。</p> <p>Kodiフォーラムにも同じようなエラーに遭遇してる方がやはり。<br /> <a target="_blank" rel="nofollow noopener" href="https://forum.kodi.tv/showthread.php?tid=348464&pid=2925301#pid2925301">https://forum.kodi.tv/showthread.php?tid=348464&pid=2925301#pid2925301</a></p> <p>リプだとaccess_manager.json削除からのAPI設定してねって書いてある。</p> <p>もう少し調べた所</p> <blockquote> <p>kodi YouTubeアドインにサインインできない問題 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/god19/items/aaab2b86fa08de5ac9d5">https://qiita.com/god19/items/aaab2b86fa08de5ac9d5</a></p> </blockquote> <p>と、@god19 さんの記事があったので参考にした。ありがたや。</p> <h1 id="注意"><a href="#%E6%B3%A8%E6%84%8F">注意</a></h1> <p>YouTubeプラグインの設定ファイルの場所は<br /> <code>/storage/.kodi/userdata/addon_data/plugin.video.youtube/~</code>にxmlとjsonがある。SSHで接続して変更するとき注意。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>APIキー発行して設定したらまた正常に見れるようになった。<br /> これで駄目だったらある意味絶望だと思う。<br /> google.com/device に登録2段階するのがまた面倒くさいが。。<br /> 自分も最近起きた事項なので、発生してない環境もあると思う。<br /> 見れなくなるエラーは結構多いみたいなので、APIキーは自分で発行して設定したほうがいいかもしれない。<br /> 早く気付けばよかった。。</p> <h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1> <p>良い子はFireTV Stick を買おう。</p> かすみん@Crieit出張版 tag:crieit.net,2005:PublicArticle/15758 2020-03-11T20:13:46+09:00 2020-03-11T20:13:46+09:00 https://crieit.net/posts/LibreELEC-Kodi-Netflix LibreELEC(Kodi)でNetflixを見る <p>この前、LibreELEC(Kodi)でYoutubeのOAuth認証エラーで見られなくなった記事を書いた。<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/ksmndevelop/items/1347e59d642364f021e5">https://qiita.com/ksmndevelop/items/1347e59d642364f021e5</a></p> <p>現在も問題なく視聴できているのでよい。</p> <p>また、Amazon プライムビデオも見れるようにしてあるのでよい。(この間も言った)<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/bda2222f-ce99-c970-d66a-c20eed6812bc.png" alt="IMG_20200221_201453501.png" /></p> <p>まぁそんなことはさておき、<br /> 今回はNetflixをLibreELECで見たいなーと思ったので導入することにした。<br /> 導入はとても簡単。Amazon プライムビデオを入れる際と同じ。</p> <h1 id="導入環境"><a href="#%E5%B0%8E%E5%85%A5%E7%92%B0%E5%A2%83">導入環境</a></h1> <p>・Raspberry Pi 4B (RAM 4G)<br /> ・LibreELEC 9.2.0 (Kodi v18.5)</p> <h1 id="ネトフリ導入の経緯"><a href="#%E3%83%8D%E3%83%88%E3%83%95%E3%83%AA%E5%B0%8E%E5%85%A5%E3%81%AE%E7%B5%8C%E7%B7%AF">ネトフリ導入の経緯</a></h1> <p>・Amazon プライムビデオが1080p(FHD)で見れない → InputStream設定はしてあるのに720p?相当になっている<br /> ※Amazon プライムビデオをPCで見た際に高画質設定でも若干画質が荒いので元々画質は良くない?<br /> ・新型コロナウイルスでお家時間が増えそうなので、この機会にネトフリを契約してみようかなーと思ったため</p> <p>YouTubeはInputStream通り、1080p(FHD)で見られる。<br /> だが、Amazonプライムビデオは見苦しいほどの画質では無いが、FHDではない。<br /> Amazonプライムビデオが1080p(FHD)で見れればネトフリをわざわざ契約してまでしなくてもいいのだが。<br /> ちなみに、アプリで見る場合は問題なく1080p(FHD)?で見れている。<br /> また、RaspberryPi 4 は4Kに対応したので4K(2160p)で出力できるが、エンコーディングがハードウェア的に難しいのであろう。<br /> せっかくの大画面でFHDじゃないのは若干寂しい。</p> <h1 id="導入"><a href="#%E5%B0%8E%E5%85%A5">導入</a></h1> <p>公式のフォーラムに書いてある。<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/5bc77247-1a1e-8437-387e-50895f436ba9.png" alt="image.png" /><br /> <a target="_blank" rel="nofollow noopener" href="https://forum.kodi.tv/showthread.php?tid=329767">https://forum.kodi.tv/showthread.php?tid=329767</a></p> <ol> <li><p>レポジトリからZIPをダウンロード<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/castagnait/repository.castagnait/raw/master/repository.castagnait-1.0.0.zip">https://github.com/castagnait/repository.castagnait/raw/master/repository.castagnait-1.0.0.zip</a></p></li> <li><p>TeraTerm等SSHクライアントでダウンロードしたZIPをラズパイに送る</p></li> <li>送ったZIPをインストール<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/438caffb-b8a0-03d9-964d-fc1326a17095.png" alt="screenshot002.png" /><br /> ホーム→アドオン→zipファイルからインストール→ZIP選択しインストール</li> <li>レポジトリからNetflix Add-on をインストール<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/00a98580-24c9-2534-0a97-c37c8392b972.png" alt="screenshot003.png" /><br /> ホーム→レポジトリからインストール→CastagnaIT Repository<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/57d6fd3f-07d3-4724-3b4e-4fc7c8a30831.png" alt="screenshot004.png" /><br /> ビデオアドオン→Netflix</li> <li>再起動後Netflixを起動<br /> 起動するとメールアドレス・パスワード(暗証番号)が求められるので入力</li> </ol> <p>これで見れるようになる。</p> <h1 id="視聴"><a href="#%E8%A6%96%E8%81%B4">視聴</a></h1> <p>Amazonプライムビデオだと1080p(FHD)で見れなかった作品が、ネトフリだとFHDでキレイに見れる。<br /> ※InputStreamの設定は各自で調べること<br /> ただ、アニメのラインナップはAmazonプライムビデオよりは少ないらしいが、私は少ないと感じなかった。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>今回、Amazonプライムビデオが1080p(FHD)で見れずネトフリを契約して導入してみたが、納得のいく結果になった。最初、自宅のネット環境がADSLだから?とは思ったのだが、YouTubeはFHDで見れているためやはりAmazonプライムビデオ自体の画質だった。<br /> だが、ネトフリはスタンダードプラン(FHD)でも月1200円するため、画質は若干落ちてもAmazonプライムビデオで良いだろう。プライム会員500円で速達・ビデオ・音楽は安い。</p> <h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1> <p>ネトフリもアマプラも契約している限りは充実した生活。。<br /> 良い子のみんなはFireTV Stick買おう。</p> かすみん@Crieit出張版 tag:crieit.net,2005:PublicArticle/15757 2020-03-11T20:08:20+09:00 2020-03-11T20:08:20+09:00 https://crieit.net/posts/Raspberry-Pi-Imager ラズパイ公式「Raspberry Pi Imager」がようやく <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/ab881bb1-ace2-9680-7c30-85d573687c32.png" alt="image.png" /></p> <p>若干遅れ気味の話です。<br /> ラズパイの書き込みツールがようやく公式から出たっていう話。<br /> 何十年も待っていたよ。。</p> <h1 id="ダウンロード"><a href="#%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89">ダウンロード</a></h1> <p>公式からだと落とすの遅いのでやはりミラーから。<br /> <a target="_blank" rel="nofollow noopener" href="http://ftp.jaist.ac.jp/pub/raspberrypi/imager/">http://ftp.jaist.ac.jp/pub/raspberrypi/imager/</a><br /> 公式はここ<br /> <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/downloads/">https://www.raspberrypi.org/downloads/</a></p> <p>Raspbian,NOOBSを書き込むのにようやく楽なツールがでた。</p> <h1 id="利点等"><a href="#%E5%88%A9%E7%82%B9%E7%AD%89">利点等</a></h1> <h3 id="今までの書き込み方(Windows)"><a href="#%E4%BB%8A%E3%81%BE%E3%81%A7%E3%81%AE%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E6%96%B9%28Windows%29">今までの書き込み方(Windows)</a></h3> <p>OS、SDカードの準備<br />  → OSを事前ダウンロードしておく・・・手間!!<br /> ↓<br /> SDカードのフォーマット<br />  → 64GB~だとexFATになるのでBuffaloのDisk Formatter とかを使う必要・・・手間!!<br /> ↓<br /> Imagerとかで書き込みor解凍でコピー<br />  → EtcherとかのImager・・・手間!!<br /> SDカードをラズパイに差して起動</p> <p>今までだとソフトを駆使してやらないといけなかったから面倒。<br /> まぁWindowsは面倒くさいっす。。</p> <h3 id="Raspberry Pi Imager が出てから"><a href="#Raspberry+Pi+Imager+%E3%81%8C%E5%87%BA%E3%81%A6%E3%81%8B%E3%82%89">Raspberry Pi Imager が出てから</a></h3> <p>SDカードの準備<br /> ↓<br /> Imager起動からのSDカードのフォーマット Erase<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/39808a88-f2d6-305d-f299-6a82f86d1a09.png" alt="スクリーンショット (11).png" /><br /> Eraseで容量問わずFAT32フォーマットできる・・・!<br /> ↓<br /> OSのダウンロード(選択)<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/4b1a9c4e-b30b-60e4-a11d-98254e0552a4.png" alt="スクリーンショット (9).png" /></p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/3976e34e-77d9-e0d5-dc6d-a4da3be9296e.png" alt="スクリーンショット (10).png" /><br /> Raspbian,LibreELECなどがImagerから直で落とせる。<br /> もちろんVolumioなど事前にダウンロードしたものを選択できる。Use custom<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/b22d5260-93f1-bc6b-c0e6-cd42a8e485d6.png" alt="スクリーンショット (11).png" /><br /> ↓<br /> SDカードセレクトしてフラッシュ</p> <p>Raspberry Pi Imagerが登場してソフトこの一本で楽に書き込みできるようになった。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>書き込みが楽になりました。<br /> 有効時間でNetflix、アマプラでアニメを見よう見よう</p> かすみん@Crieit出張版 tag:crieit.net,2005:PublicArticle/14937 2019-04-20T12:08:57+09:00 2019-07-02T19:43:14+09:00 https://crieit.net/posts/C-Cerflet C++ ベースのウェブアプリケーションサーバ Cerflet のご紹介 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet">Cerflet</a> は <a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch">Maya Posch</a> さん作の C++ ベースのシンプルな Web Application server です<br /> Raspberry Pi でもサクサクに動いています</p> <p>python の tornado みたいにリクエストハンドラを書くだけで簡単に使える上に、<strong>オール C++</strong> かつ<strong>オンメモリ</strong>なので超高速が期待できます</p> <p>ちなみに Cerf はジビエ好きな方はピンと来るかと存じますが多分、フランス語の <strong>鹿(セール)</strong> なんじゃないかなと想像してます、Maya さんの他のプロダクトも動物の名前のが多いし、彼女の会社の名前からして <a target="_blank" rel="nofollow noopener" href="http://www.nyanko.ws">Nyanko</a> だし</p> <h1 id="実装"><a href="#%E5%AE%9F%E8%A3%85">実装</a></h1> <p>本体の<a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/lib/httpcerflet.cpp">実装</a>は物凄くシンプルでコメント込で 80行ぐらいしかないです、すごい<br /> 私だったら C++ の80行ってコマンドライン処理するだけでもゆうに超えちゃったりします</p> <p>サーバの処理も実行時オプションの処理も <a target="_blank" rel="nofollow noopener" href="https://pocoproject.org/">POCO</a> の機能が有効に使われてて、POCO の凄さと、POCOを使えば Web Application でさえこんなにシンプルにつくれるという Maya さんのソフトウェア・アーキテクチャのセンスの良さに敬服いたしますとともに、Poco.Net のプラグマティックなチュートリアルとして大変ありがたく読ませていただきました次第でございます</p> <h1 id="How to try it"><a href="#How+to+try+it">How to try it</a></h1> <ol> <li>POCO を<a target="_blank" rel="nofollow noopener" href="https://pocoproject.org/download.html">インストール</a></li> <li>git clone https://github.com/MayaPosch/Cerflet.git</li> <li>cd Cerflet/sample</li> <li>make</li> <li>./hellocerflet</li> </ol> <p>「libPocoNet.so.60 がないよ」とかエラーになるようでしたら <a href="https://crieit.net/posts/POCO-error-while-loading-shared-libraries-libPocoNet-so-60-cannot-open-shared-object-file-No-such-file-or-directory">ldconfigして</a>みてください</p> <p>で、hellocerflet を起動したサーバの port 8080 番をブラウザで開くと</p> <p><a href="https://crieit.now.sh/upload_images/7cc81f710697ae3e872d25b283d8f9535cba83edb5f74.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7cc81f710697ae3e872d25b283d8f9535cba83edb5f74.png?mw=700" alt="スクリーンショット 2019-04-20 11.27.15.png" /></a></p> <p><strong>ビックリするほど簡単</strong>です</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/sample/HelloCerflet.cpp#L22">こちら</a> の HTTPRequestHandler の中身を変えて、たとえば ContentType を "text/html" じゃなくて <strong>"application/json"</strong> にして、<a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/sample/HelloCerflet.cpp#L32">ostr</a> に <strong>json 文字列</strong>を返したら超高速かつコンパクトな API サーバーとしてすぐにでも大活躍しそうです</p> <h1 id="作者の御紹介"><a href="#%E4%BD%9C%E8%80%85%E3%81%AE%E5%BE%A1%E7%B4%B9%E4%BB%8B">作者の御紹介</a></h1> <p>作者の <a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch">Maya Posch</a> さんですが、<a target="_blank" rel="nofollow noopener" href="http://www.mayaposch.com/autobiography.php">御本人のブログ</a>によると生まれつきに抱えるいくつかの問題、特に<strong>両性具有</strong>に起因する問題(当時のニュース番組が<a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=M4N-0CgUCX8">これ</a> とか <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=DKW2c0H2iGw">これ</a> とか残ってます)で祖国オランダを離れざるを得ず、安住の地を求めて世界を旅しながら自分の会社 <a target="_blank" rel="nofollow noopener" href="http://www.nyanko.ws/">Nyanko</a> を運営しつつプログラミングと電子工作に関する<a target="_blank" rel="nofollow noopener" href="http://www.mayaposch.com/index.php">数々のプロダクトと著作</a>を世に出していらっしゃいます<br /> まるで物語みたいに数奇な人生を歩みながら outcomes を出されていることに正直圧倒されてしまいました、すごい人がいるもんなんだなぁ<br /> 翻って自分を鑑みるにいったい何をやってるんだと情けなく忸怩たる思いに至る次第です</p> <p>近著 <a target="_blank" rel="nofollow noopener" href="https://learning.oreilly.com/library/view/hands-on-embedded-programming/9781788629300/">Hands-On Embedded Programming with C++17</a> を魅力的なタイトルに惹かれて読んだのが彼女を知るきっかけだったんですが、この本も POCO の紹介をふくめて Raspberry Pi みたいなSBC でプロダクトをつくる上でのオリジナルな話題にあふれていてとても面白い本でした</p> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>数日前に<a href="https://crieit.net/posts/Nuitka-python-code">某所</a>で「C++でウェブアプリ書く気にはならないし」なんて言っちゃったの、謹んで取り消させてください</p> <p>読書は時として人の世界観をダイナミックに変えてしまうものなのです ^^;;;;;;;</p> Dr. Takeyuki Ueda