EPGStation × n8n × Gemini でAI録画コンシェルジュを組んでみた

昨今の生成AIとワークフローオートメーションを使って、もう10年以上ガチ安定で稼働している自宅のEPGStationの録画サーバーに「AIがオススメする録画候補番組リスト」という新機軸を追加する試み。構想30分、構築一週間くらいの作業記録です。

今回はひとまず全て無償の枠内で動かすことを前提に。APIの無償枠が安定して使えるのはおそらくGeminiだけなので、Geminiで組みました。

成果物

Geminiがオススメ番組を選んでリストアップしてくれるWebページ。

  • 過去の録画実績と、個別にプロンプトで指示した条件を元に、Geminiが私と家族の視聴傾向を判断して放送リストの中からオススメ番組を拾ってくる
  • リストには予約ボタンがついていて、直接EPGStationに予約登録ができる。予約済みの番組はグレーアウトする
  • リストは一日に二度、朝と晩に更新される
  • 長すぎてもアレなので、現状では提案件数は最大30件までに制限

サンプルのn8nワークフロー

そのままでは動かないだろうが参考までに。n8nにインポートすれば手軽に雰囲気は分かると思う。各ノードの設定やJavaScriptについてはこちらを参照していただきたい。実際に動かすにはData Tableの作成や環境変数の設定、Gemini API連携の設定などの作業が必要。環境固有の情報はダミーに入れ替えてある。

AI推奨番組ダッシュボード試作品.json 

自宅のLAN内でのみ使う前提なので、CORSを全開で許可していたりなどセキュリティ的には甘い作りになっている点には注意していただきたい。またコードは全てGeminiに書いてもらっているのでコメントや注釈は一貫性に欠けているかもしれない

使ってみた感想

  • リストに上がってくる番組は「惜しい」ものが多く、実際に予約に至るのは一回の提案に一番組あるかないかで打率は低い。しかし自分で手検索するよりは効率はずっと高く、母集団のフィルタリングとしては十分に効果的。プロンプトの改良や学習方法の変更で良くなる可能性が高いので、またトライしたい
  • 推奨理由が面白い。たまに、自力では到達しないであろう番組を引っ張ってくるのも味わい深い
  • 毎日推薦された番組リストを見てるだけでも結構楽しめるので、良しとする

では、ここからは構築について。

前提となる環境

  • EPGStationでの録画システムが既に稼働中であること
  • そのホストであるLinuxサーバーが稼働していること(WindowsでもOK)
  • Dockerが動かせること

筆者のスペック

  • Linuxの一通りの操作ができてEPGStationを動かせる程度のスキル
  • コードは全く書けない。簡単なシェルスクリプトがギリ
  • n8n、というかワークフローオートメーション系を触るのはこれが初めて

やりたいこと

  • 自分が興味を持ちそうな番組の候補をAIに探させて提案してもらう
  • 提案リスト内から直接録画予約ができる(EPGStationに戻らなくていい)
  • 定期的に勝手に動いて提案してくる

作業の進め方

上記の構想と成果物のイメージをGeminiに示して、EPGStationとn8nを使いたいと伝えたら、あとはひたすらGeminiと会話して指示に従って組んでいく。マンツーマンの講師がついたワークショップみたいな感じ。n8nをどう使い始めるのか?から教えてくれるし、JavaScriptも秒で書いてくれる。はっきり言って信じられない。なんつー世の中だ。。ただしこの講師は当然ながら色々と間違えるので、付き合い方を学ぶ必要がある。初めて本格的にAI対話型で組んでみた感想はこのエントリの後半に。

実際の構築手順

  1. Ubuntu上にDockerでn8nを導入する
    導入手順はGeminiが教えてくれる

  2. Dockerのdocker-compose.ymlにn8n用の環境変数とアクセス許可を設定する。太字の部分
    ==================
    version: '3.8'
    services:
      n8n:
        image: n8nio/n8n:latest
        container_name: n8n
        restart: unless-stopped
        ports:
          - "5678:5678"
        volumes:
          - ~/n8n_data:/home/node/.n8n
          - ~/n8n_data/tmp:/tmp
        environment:
          - N8N_SECURE_COOKIE=false
          - GENERIC_TIMEZONE=Asia/Tokyo
          - TZ=Asia/Tokyo
          - N8N_RESTRICT_FILE_ACCESS=false
          - N8N_RESTRICT_FILE_ACCESS_TO=/tmp
          - EPGSTATION_URL=http://[EPGStationのホスト名またはIPアドレス]:8888
          - N8N_WEBHOOK_BASE_URL=http://[n8nのWebhook用ホスト名またはIPアドレス]:5678
          - N8N_BLOCK_ENV_ACCESS_IN_NODE=false

  3. Google AI StudioでGemini APIを有効にする
    この手順もGeminiが教えてくれる

  4. n8n上にData Tableを作成する
    ai_cacheという名前で作る。keyはlatestのみ。こんな感じになる

  5. n8n上にノードを配置していく

ワークフロー構成

全体像はこんな感じ。

処理のざっくりした流れはこう。

  1. EPGStationから、向こう2日間の番組表、予約済み番組リスト、録画済み番組リスト、の3種類のデータをAPI経由で取得する
  2. 取得したデータを合流させて整形し、余計な情報を削ってデータ量を絞る
  3. 絞ったデータにプロンプトを添えてGeminiに食わせる
  4. Geminiから出てきたオススメ番組リストをn8nのData Storeに保管する
  5. リストが更新された旨をメールで利用者に通知する
  6. 利用者がWebブラウザでオススメ番組リストにアクセスする
  7. n8nがData Storeから番組データを読んでHTMLを生成してブラウザに返す
  8. 録画したい番組の予約ボタンを押すとEPGStationにPOSTが飛んで予約が実行される

各フェーズとノードごとにもう少々細かい説明をする。

1. データ収集・前処理フェーズ(定期実行)

まず最初にEPGStationからAIの判断材料となる生データを収集する。

  • Schedule Trigger
    n8nのワークフローは、起動タイミングを規定するTriggerタイプのノードから開始するルールになっている。今回は毎日 07:15 と 18:15 の2回、ワークフローを自動で走らせることとした。一日の間に頻繁にオススメリストを更新してもあまり自分には意味がないので、朝晩の2回更新で良しとする。
  • HTTP Request (schedules)
    予約候補となる番組リストの母集団をEPGStationからSwagger APIで取得する。EPGStationは向こう一週間の全チャネルの番組表を持っているが、これを全部取得すると相当なデータ量になってしまい、後ほど後段でGeminiに投げる情報量が多過ぎてトークン上限をオーバーするので、この段階である程度範囲を絞る必要がある。まず、私はCSはほぼ見ないので、取得対象は地デジとBSのみとした。さらに対象レンジはタスク実行時から1日先~3日先の2日間とした。さらに放送局を絞って、代わりに期間を延ばすなどのアレンジをここで行うことも可能だが、それは後段で実施することとして、一旦これで行く。
  • HTTP Request (recorded)
    EPGStationですでに録画済みの番組リストを取得する。すでに録画された番組は利用者の視聴傾向を反映しているはずなので、このリストを後ほどGeminiがユーザーの好みを分析するための材料として利用する。
  • HTTP Request (reserves)
    EPGStationで現在すでに予約登録されている番組リストを取得する。すでに予約済みである番組がGeminiから重複推薦されないように、除外リストとして使用する。
  • Merge
    上記3つのAPIから取得した異なるデータを一つの流れに統合し、以降の処理を一本にまとめられるように整形する。
  • Trim (Codeノード)
    取得した生データから必要な項目(タイトル、概要、IDなど)のみを抽出し、既に予約済みの番組を候補から除外するなどの整理を行う。
  • Aggregate
    分散しているデータアイテムを一つにまとめ、次の「絞り込み」工程に渡せる形式に整形する。n8nはアイテムの単位で処理を実行するので、ここでまとめておかないと後段でGeminiにバラバラのリクエストが複数回に分かれて投げられることになり、期待する回答が得られなくなる。
    ※考えてみると前段のTrim内でも同じ処理を実行できるので、このノードは削れるかもしれない

2. AI向け最適化・推論フェーズ

AIが効率よく正確に判断できるようにデータを加工し、さらにデータ量を絞り、その上でプロンプトとして投入する。本システムのキモとなる部分。

  • Slim for Gemini (Codeノード)
    前段で放送種別や時間帯を絞って番組表を取得したが、それでもなお生の番組リストは情報量が多く、絶対に録画対象にならない番組や、AIの処理には不要なデータが大量に含まれているので、ここでそれらを除外する。放送局名、キーワードリスト、放送時間(10分以下)での除外を併用してフィルタリングする。関東地方での地デジとBSでは2日間で概ね2000件程度の番組が放送されるが、このノードでこれを約700件程度まで絞り込む。さらにAI処理およびその後段で必要になる情報(タイトル、概要、ID、開始時刻)以外をカットし、Geminiに渡すデータ量を減らす。

  • Prompt (Codeノード)

    Geminiに対してのプロンプトを書くノード。プロンプトは後段のGeminiノード内に書いても構わないのだが、流れで作業していたらここで書く作りになった。プロンプトに含めるべき要素は大きく3つある。

    • まずは「選定の基準と指針」。利用者の関心があるもの、逆に興味がないもの、優先度を上げて/下げてほしいもの、などの指示をキーワードや文章でAIに伝える

    • 次に「出力形式」。後段で正しく処理ができるように、データの出力形式をシンプルかつ明確に指定する。ちゃんと定義しておかないと出力の揺れが発生して処理がエラーになったり、推奨データがおかしなことになったりする。特に各番組の一意の識別子となるProgramIDは確実にキープするよう指示する
    • 最後に「抽出用の元データ」。前段で整形した番組表と、嗜好判断用の録画済み番組リストを渡す

      プロンプト自体はこのエントリのもう少し先に記載した。

3. 保存・通知フェーズ

Geminiの出力した推奨リストをローカルストレージに保存し、ユーザーに更新完了を通知する。

  • Upsert row(s)
    Geminiが選んだ推薦番組リストと、詳細情報を含むマスターリストを、n8n内部のデータテーブル(ai_cache)に保存する。データテーブルは直近のGeminiの出力結果だけを保持する超シンプルな作り。ワークフローが走るたびに毎回更新され、最新の結果で常に上書きされる。過去の情報は持たない

  • Send email
    ダッシュボードの更新をメールで通知する。ユーザーは自分と家族しかいないし、日に二度実行されることは分かっているので必須ではないし、処理が失敗したときにだけエラー通知すれば用は足りるのだが、しかし正常に稼働してますよというプッシュ型通知の意味と、あと通知が届くとなんとなく嬉しいので賑やかしとして付けた。

4. ユーザーインターフェース(ダッシュボード)表示フェーズ

ユーザーがブラウザで推薦結果を確認して予約操作を行うためのWebページを生成するプロセス。独立したサブワークフローとして設置する。このフローをメインのフローに結合してしまうと、ページを開くたびにGeminiが走って処理が非常に重くなる上に、早々にトークン超過で利用不可になってしまうので、ダッシュボードを表示するだけの別プロセスとして切り離す。

  • Webhook-dashboard
    Webサーバーの口としてHTTPリクエストを待ち受ける。リクエストを受けて以降のワークフローをキックする

  • Get row(s)
    データテーブルから最新のAI推薦データを読み込む
  • HTTP Request (reserves)2
    ダッシュボードを表示する瞬間の最新の予約状況をEPGStationから取得する

  • Prepare Webhook URL
    環境変数からWebhook用のURLを取得して後段のCodeノードにwebhook_urlとして渡す。n8nではCodeノードでJavaScriptから直接環境変数を読めない(とGeminiが言っていた)ので、このノードを追加する流れになった
  • Dashboard (Codeノード)
    読み込んだデータをHTML/JavaScriptに変換し、番組名、推奨理由、「予約ボタン」が並ぶWeb画面のデザインを生成する

  • Respond to Webhook
    ブラウザに対して、完成したHTMLダッシュボード画面を返送する

5. 予約実行フェーズ

ダッシュボード上の予約ボタン押下を受けて実際にEPGStationに録画予約を行うプロセス。

  • Webhook-reservation
    ダッシュボードの「予約する」ボタンが押された際に発行されるPOSTリクエストを待ち受ける。POSTリクエストには番組IDが含まれる

  • POST to EPGStation
    受け取った番組IDをAPI経由でEPGStationにPOSTリクエストとして送信し、録画予約を確定させる

Geminiに渡すプロンプト例

# ROLE
あなたは、私が視聴するべき番組を選定し推奨する専任コンシェルジュです。

# HOW TO THINK
- 【REFERENCE】から私の視聴傾向・好みを推定してください
- 【CANDIDATES】の中からのみ、推薦番組を選んでください
- 【REFERENCE】に含まれる番組自体を推薦してはいけません

# USER PREFERENCE (EXPLICIT)
・関心があるもの:
  旅行、日本の地方文化、美術、芸術、音楽、自然、動物、鉄道、
  ドキュメンタリー、料理、食事、日本の伝統、離島、宇宙

・関心がないもの:
  バラエティ、スポーツ中継、通販、ショッピング、釣り、自動車

・注目キーワード:
  北海道、富山、瀬戸内、山陰、孤独のグルメ、tiny desk concert

# SELECTION RULES
- 再放送(タイトルに [再] を含む番組)は優先度を下げる
- スポーツの試合中継番組は優先度を下げる
- 選定する番組のカテゴリーが極端に偏らないようにする(条件に該当する番組が少ない場合は偏っても可)
- 最大で30件まで選定(条件に該当する番組が少なければ30件未満でも可)
- あなたは、私の視聴傾向に必ずしも合致しない可能性がある番組を、最大で3件まで、あなたの判断で選んでも構いません

# OUTPUT
 - 選定した番組の ID [programId] と 番組名 [title] と 推薦理由 [reason] のみを、以下のフォーマットのJSON形式で出力してください
   [{"ID": "...", "title": "...", "reason": "..."}]
 - IDに格納するprogramIdの値は元のデータから一切変更せず、そのまま用いてください

# REFERENCE: WATCH HISTORY(嗜好推定用・参考情報)
${recordedText}

# CANDIDATES: PROGRAM GUIDE(推薦候補・ここからのみ選択)
${schedulesText}

開発アシスタントとしてのGeminiの使い勝手

  • FlashとThinkingを意図的に使い分けると効果的。全体デザインはThinkingで、個別のノード設定やシンプルなJavaScriptの作成はFlashで。Flashで何回試してもコードが修正できない場合はThinkingに切り替える。n8nはワークフローをJSONファイルとしてダウンロードできるので、行き詰ったらJSONをGeminiに食わせてThinkingモデルで全体レビューと解決方法の提案をしてもらうと突破しやすい
  • 特にFlashモデルはフロー全体のデザインや整合性を俯瞰で見るのが苦手なので、今の作業は本当に期待するゴールに向かっているか?は自分で配慮しながら進める必要がある。任せきりにすると、例えば推奨リストを見るたびに毎回Gemini APIを叩く(=アクセスの度に長時間待たされる上にトークンがすぐに上限を超える)デザインを提案してきたり、データの保管先に生のJSONファイルを使おうとしたり、何もかもGeminiへのプロンプトに投げ込もうとしたりする。「これはおかしくね?」とか「違う手段のほうがいいのでは」と思ったら迷わず指摘するのが重要
  • Geminiは比較的粘りと頑張りに欠けていて、ある意味現実的なところがあり、何度か試して上手くいかない課題があると、正面突破を諦めて別の回避策を提案してくる傾向がある。提案は妥当なこともあるが、雑で安易な逃げの手だったりもするので、採用するかどうかの判断はしっかり行う。ちなみにChatGPTは愚直に課題に挑むが解決できずにループに陥ったりする。キャラクターの違いが中々味わい深い。クールで冷静なClaudeが一番こういうのには向いている気がする
  • n8nの使い方に関しても詳しく教えてくれるが、情報が古かったりして、実際にメニュー内に存在しないオプションを設定するよう指示することが頻繁にある。その都度、実際のメニューはこうなっているが、どうすればいいか?と再質問するか、自分で適当に設定した上でJSONを食わせてチェックを依頼するといい
  • スクリプトはすぐに書いてくれるが、動かないことも多い。一発で成功すると思わず、エラーの情報を与えたり前段からのデータを添えるなどして、周辺情報を与えつつ何度か修正を繰り返して徐々に先に進んでいく。トライアンドエラーとブラッシュアップを粘り強く繰り返す。粘り強く、と言っても自分一人でやるより100倍速いので文句は全くない。しかも無償だし。あなありがたや
  • Geminiが書いたコードをChatGPTなどの別のAIに評価させるのもアリ。Geminiが書いたコードをChatGPTがコキ下ろすシーンに何度か遭遇し、結構笑えた

今後やりたい追加実装

  • 録画済み番組だけではなく、予約済み番組も傾向把握材料としてGeminiに食わせてもいいかもしれない。あんまり変わらなさそうだけど
  • Aggregateノード周辺の処理は少々冗長な気がするので見直したい
  • 傾向把握に使う録画履歴は「その時点でEPGStation上に残っている録画の最新100件」のみを都度使う作りになっている。つまり長期間の視聴傾向の蓄積はしていないし、使い込むほどGeminiのアルゴリズムが洗練されたりはしない、なので、時間経過とともに育つコンシェルジュに挑戦したい。今のGemini APIでは過去の会話の履歴を長く引き継げないはずなので、ちょっとハードルが高そうだが...

苦労したところ

  • 番組表のデータ量なんて大したことないでしょと思っていたがそんなことはなかった。当初は一週間分まるっとEPGStationから拾って全部Geminiに食わせりゃOKなどと安易に考えていたが、秒でトークン超過することが分かり、データの品質をキープしつつ量を削る手法を考えるのに結構な時間を使うことになった
  • 初期段階でGeminiの指示に安易に従った結果、推奨番組リストも含めたHTMLダッシュボード出力までの全てをGeminiに任せるフローが組み上がった。これは上手く動くこともあるが結構な確率で失敗する(Geminiからの出力がブレてHTML構造が壊れる)上にトークン量が増加するという欠点があり、路線転換するのが結構面倒であった
  • Geminiからの出力データを毎回同じ形式になるよう厳密に守らせるのが意外と大変であることが分かった。例えば、この構築の初期段階では、Geminiに推奨候補を選ばせるだけでなく、それをリスト化してHTMLページを生成するところまでを全部やらせようとしたのだが、実行のたびにタグ構造が壊れたとかJSONじゃないとかスクリプトエラーだとかバリエーション豊かなパターンでフローが失敗して使い物にならなかった。これを防ぐために、Geminiからの出力は最小限のデータ量で極力シンプルな形になるよう変更し、HTMLの生成や予約済みデータとの照合は別途切り出してJavaScriptでの実装とした。適材適所ということである
  • 同様にGeminiが長いリンクの文字列を何故か一部だけ変更してしまいリンク切れになる問題が多発したので、明示的に変更しないよう指示して概ね抑制できるようになった(それでも極稀におきるが)

その他雑感など

  • 月並みな感想だが生成AIヤバい。Web開発経験はなく、コードも書けず、ワークフローツールに触ったこともない程度の人間がちょっと作業しただけでこのくらいの仕組みを組めてしまうとは。なんつー時代だ
  • 毎度のことですがDocker様本当にありがとうございます
  • EPGStationの作者様に改めて感謝。今回ようやくAPIをフル活用できました
  • 一部のベンダーがノーコードノーコード騒ぐ理由を実感できた
  • 今回は推奨番組ダッシュボードという形式にしたが、ちょっとアレンジすればn8nが勝手にEPGStationに録画登録する形にすることも可能。しかし今のところは打率が低いので、最後は人の手で選ぶのがちょうど良さそうである
  • 少し時間が経過したら、このようなフローを組まずとも、OpenClawとかでもっと簡単な指示で勝手にニーズを満たしてくれるようになりそうな気がする

 

では皆さま、よい録画生活を。

 

 

 

 

Google Cloud上にUptime Kumaで監視サーバーを建ててTailScale経由でLAN内監視をするメモ

できるだけ簡単に低コストで自宅内環境の死活監視をしたい、ということで環境を組んだ際のメモです。一応自宅LAN内に普通に監視サーバーを立てれば監視はできるんですが、それだと

  • 監視サーバー自体の障害を検知できない
  • 自宅のネット回線が落ちるケースでは通知が飛ばせない

という課題があり。次にSaaS型の監視サービスの利用を検討したんですが、有償かつ機能がリッチすぎる商用サービスが大半(そりゃそうだ)で今回の目的にはちょっと合わないな、ということで、さらにシンプルな方法を探して行きついたのがこの構成です。

やりたいこと

  • 自宅のルーターとサーバの死活監視がしたい。死活監視だけでいい
  • とにかく簡便に構築したい。設定ファイル弄り回したりDB建てたりしたくない。ネットワーク周りも触りたくない。Firewallに穴開けたりするのも面倒
  • 極力低コストで運用したい

利用したサービス

やったこと

  • 自宅側のアクセスルータとしてOpenWrtを用意し、そこでTailScaleを稼働させる
  • Google Cloud上に無償利用枠内(e2-micro)のVMインスタンスUbuntuで建てて、監視ツールのUptime Kumaをdocker composeで立ち上げる。さらにTailScaleを動かして自宅とつなぐ
  • 自宅のデバイス群はTailScale経由でUptime Kumaで監視する
  • Uptime KumaとホストのVMマシンは、Google CloudのUptime Check機能で監視する

Uptime Kumaのコンソール画面

出来るようになったこと

  • 自宅の何かしらが止まるとUptime Kumaからメールが来る。メッシュの端のルーターが落ちたとか、録画用サーバのEPGStationが止まった、とかが分かる
  • Google Cloud上のVMマシン、ないしはその上で動くUptime Kumaが止まると、Google CloudのUptime Checksから通知が来る

作ってみて

  • Google Cloudの利用費が月額14円程度発生する。完全無償とはならなかったが、駄菓子以下なので良しとする
  • 連続稼働時間が長くなると、Uptime KumaがOOM Killerで落とされることがある。毎週日曜早朝にUbuntuごと再起動することで回避した
  • 毎度のことだがTailScaleが画期的すぎる。技術的に強力なのはもちろん、ユーザーエクスペリエンスが最強すぎる。感服いたします
  • Dockerさん本当にありがとうございます。コマンド一発で監視サーバーが起動できるなんて誠にありがたやありがたや
  • Google Cloudさん、VMインスタンスの無償枠提供に感謝を申し上げます

 

かつてはPrometheusでGrafanaに連携して地球防衛軍みたいな派手なダッシュボードでテレメトリーやらメトリクスを一括可視化でどうのこうの、みたいなこともしたけれど、もはや自宅システムの監視にそこまで手間をかける元気はなく。こういうのでいいんだよ、こういうので、的な実用性重視の自宅監視をしたい方はご参考になさってください。

 

では良い監視ライフを。

 

 

 

OpenWrtを使ってWi-Fi中継器(エクステンダー)を構築する

OpenWrtでのWi-Fiエクステンダー構築については、本家に構築ドキュメントが公開されていて、こちらに沿うのが確実な方法です。当記事は、これを参考にしつつ自分の構築用にメモを残したものです。

序文

先日、嫁さんがしばらく実家からリモートワークをすることになったのだけど、仕事をする部屋が離れにあってWi-Fiルータの電波が十分に届かないらしい。終日スマホテザリングをすると帯域制限に引っ掛かりそうということで、OpenWrtを中継器に仕立てて、電波の届く距離を延ばして対処することにした。

上流の親ルーターは10年以上前の802・11bgnのみ対応の古いバッファロー製のやつで、速度もおそらく出ないのだが、今回は既存の環境には変更を入れたくないので、上流はそのまま使うことにする。

Wi-Fiブリッジをどう組むか?

一台のOpenWrt上にWi-Fiクライアントとアクセスポイントをそれぞれ作成して、両者間で透過的にネットワークブリッジを成立させる方法は(おそらく)3パターンある。

  1. WDS(Wireless Distribution System)を使う
  2. メッシュ(802.11s)を組む
  3. Relay Bridgeを作成して必要なデバイスを連結する

1は最も簡単な方法だが、親ルータがWDSに対応している必要があり、今回はその可能性は皆無なので却下。2も当然ながら親ルータがメッシュ非対応なので不採用。従って3のRelay Bridgeで組むことにする。

注意点として(OpenWrtでの)Relay bridgeはIPv6の透過に制限があるらしく、IPv6環境では色々と手を入れないと上手く動かないらしい。幸い今回はIPv4環境なのでこの制限は該当しない。

ネットワーク構成

今回の要件

  • ルーターの下にOpenWrtをWi-Fiエクステンダー(L2透過ブリッジ)としてブラ下げて、2.4GHzで受けて5GHzで中継する
  • Wi-Fiクライアントが親ルーターから直接DHCPIPアドレスを取れる
  • 有線/無線クライアントからluci/SSHにアクセスできる
  • OpenWrt自体がインターネットに出られる
  • tailscale経由で遠隔地からluci/SSHにアクセスできる(保守用)

使うハードとソフト

  • Cisco Meraki MR42(手持ち機材の中で送受信性能がベスト)
  • OpenWrt 24.10(23系でも同じだが)

構築手順

  1. OpenWrtの2.4GHzアダプタ上に、親機に接続するためのwirelessクライアントを設定し、親機に接続できることを確認する

  2. 上流用のネットワークインターフェースを新規作成する。名前は何でもいいが、ここではwwanとする。プロトコルDHCPとし、use default gatewayにチェックが入っていることを確認する。手順1で作成したクライアントが使用する物理アダプタをデバイスとしてwwanに紐づける。設定したら一旦wwanをrestartし、親機からDHCPIPアドレスを受け取れていることを確認する

  3. 手順1で作成したwirelessクライアントのネットワークにwwanを紐づける

  4. Firewallのゾーン設定で、lanゾーンにwwanを紐づける

  5. OpenWrt自体がインターネットに出られることを確認する。Ping等で適当に

  6. Relay bridge用の追加パッケージをインストールする。
    # opkg update && opkg install relayd luci-proto-relay

  7. OpenWrtの5GHzアダプタ上に、クライアントデバイス向けのアクセスポイントを設定する。ネットワークにはlanを紐づける

  8. lanインターフェースのuse default gatewayが外れていることを確認する

  9. lanインターフェースのIPアドレスを、親機と同じセグメント内でありなおかつDHCPの割り当てレンジ外のものに変更する。必要に応じて、このセットアップを行っているクライアントデバイスのIPも変更する(しないと接続できなくなる)。ここでlanに割り振ったIPアドレスがOpenWrt本体へのアクセス用アドレスになる

  10. OpenWrt上にRelay Bridgeインターフェースを作成する。名前は何でもいいが、ここではrelaydとする。作成したrelaydにwwanとlanを紐づける。relaydにはIPアドレスは割り当てず空欄とする

  11. 手順7で作成したアクセスポイントにクライアントPCを接続し、以下を確認する
    • 5GHzのアクセスポイントにWi-Fi接続ができる
    • DHCPIPアドレスが取得できる
    • インターネットへ疎通ができる
    • OpenWrtのSSHおよびluciに接続ができる

  12. ここまで成功すればブリッジとしての設定はOK。続けてtailscaleをインストールし、tailscaleネットワークに接続ができ、別のtailscaleクライアントからOpenWrtのSSH/luciにアクセスができることを確認する

上記の通りインターフェースを設定すると、luci上ではこのように見える。

以上お疲れさまでした。

構築時の注意点

  • OpenWrt本体がインターネットに出るために、wwanのみでuse default gatewayを有効にする。それ以外のインターフェースでは全て無効にする
  • DHCPは親機のみとし、OpenWrtの全てのインターフェース上でDHCPサーバを無効ないしは停止に設定しておく。dnsmasq自体をdisableにしておいてもいい

メモと雑記

  • relaydはL3での疑似ブリッジであり、ブリッジの前後でL2(MAC)セグメントが分割されてしまうため、OpenWrt自体をインターネットにアクセスさせつつ同時にクライアントからluciを開けるようにする、という条件を満たそうとすると設定が若干トリッキーになる。今回はその解決のために、lanとwwanにそれぞれ同一セグメントの異なるIPアドレスを割り当てる形とした
  • WDSや802.11sのメッシュはL2での透過的アクセスができるので、使えるのであればこれらがベター。relaydを積極的に使う理由はない
  • 考えてみると、親機とローミングを組むわけではないし、同一ネットワーク内の別デバイスと相互通信するニーズもないので、ブリッジにこだわらずシンプルに二重ルータ方式で構築したほうが早かった気がする(苦笑)

 

以上。皆さんよいOpenWrtライフを。

 

 

FortiWifi 50E-2RにOpenWrtを導入したメモ

安価に売られているネットワークデバイスをなんとなく買ってOpenWrtを入れて棚にしまうだけのシリーズ、今回はFortinet社のFortiWiFi 50E-2R。

FortiGate 50EとFortiWifi 50E-2Rの違い

名前の通り、2RにはWi-Fiが搭載されていることがおそらく唯一の違い。他は完全に同じと言っていい。Wi-Fiバイスが追加されたためか、電源の要求スペックが50Eの2Aに対して50E-2Rは2.5Aに上がっている。実際の消費電力が2Aを超えるシーンは、ご家庭での利用上ではあまり発生しそうにないが。

OpenWrt導入手順

これも50Eと一緒。musashino先生のサイトの手順に従うのみ。ただし一点だけ事前準備でinitramfsイメージの名前を変える必要があり、その方法はこちらのサイトに掲載されている。毎度ながら先達の知恵に感謝。

Wi-Fi周りの実装

マザーボードの表と裏にmini pcieスロットが一つずつ実装されていて、それぞれにGmtekというメーカーのAtheros QCA9880のカードが刺さっている。

OpenWrt上ではこのように見える。

Fortinet 50E-2RでのWifiアダプタの状態

どちらのカードでも5GHzと2.4GHzの全ての周波数帯を利用できるが、カード1枚につきアダプタも1系統となる。カード1枚に対して5GHzと2.4GHzのアクセスポイントを2つ作成して同時に異なる周波数帯で稼働させることはできない。

また、OpenWrtから見える1枚目のカード(マザボ裏側)では、5GHzは普通に使えるが、2.4GHzの性能は送受信性能が著しく低く、ほぼ使い物にならない。2枚目(表側)は逆で、2.4GHzは問題ないが5GHzが使えない。2枚のカードは完全に同一型番なので、おそらくマザーボード上のアンテナ線のどこかで減衰をかけているのだと思われる。従って結局のところは普通に5GHzと2.4GHzを1系統ずつ積んだルーターとして利用することになる。

しかしこれだと何だか面白くないので、アンテナケーブルを別途用意して無線カードに直結してみたところ、やはりどちらのカードでも2.4Ghz/5GHzともに普通に動くようになった。マザボ上で減衰されているのはほぼ確実と言って良さそうである。ただしアンテナは2本しかないので、2枚のカードでアンテナを共用して両方5GHzを喋らせると同時通信時に通信速度が著しく下がる(当たり前)。なので実用性はあまりない。もう一系統アンテナを別に用意してやれば同時にフルで5GHz稼働できるが、そこまでやる意味があるのかかなり微妙である。

またコネクタの種別がややこしいので、ケーブル線の購入にあたっては間違えないようにしたい。本機にデフォ搭載されているカードに適合するのはU.FLとかIPX(の1.13mm)とか言われるコネクタである。私はAliexpressのTUOLINKで調達した。

二股分岐の同軸ケーブル。これは間違えて買ったほう(苦笑)

私のゲットした個体は純正アンテナが欠品していたので(おかげで安価だった)自宅に転がっていたTP-Link C7用のアンテナを適当に装着した。この状態での送受信性能は、Baffaloのエントリーグレードの家庭用ルータ並み。NetgearやLinksysのルータと比べると劣る。自宅の同一フロア内であれば普通に使えるが、階を隔てるとちょっと厳しい。まあ50E-2RのWi-Fiの利用目的は中小企業オフィスでの無線LANセキュリティの向上であって、例えばおかしなアクセスポイントが周辺にないかスキャンして監視する、みたいな用途のために使うものらしく、通常の無線アクセスポイントとしてゴリゴリ使う想定ではないのだろうから納得はできる。

SSDは動くのか?

動かないだろうなあと思いつつ、宅内に転がっていたmsataのssdをmini pcieスロットに刺してみたが、やはり認識されなかった。msata兼用スロットではないようである。片系のwifiカードをssdに交換できれば、overlayが小さい問題を解決しつつ無線も使えてバランスのいいデバイスになるのだが、残念。

メッシュに組み込む際のひと手間

このデバイスのAtheros QCA9880は、OpenWrtにデフォルトで入っている"-ct"ドライバだと802.11sのメッシュが動かない。メッシュアクセスポイントとして動かす場合は、ctナシの無印ドライバに入れ替えること。opkg list-installed | grep ath10kで探して、ct付きのドライバとファームウェアの2種類を変更する。

余談

マザーボードの隅っこには「FG-51E」とシルク印刷されている。51EはSSD搭載モデルのはずだが、基盤は共通なのだろうか。

所感など

  • Wi-Fiを搭載しているので、50Eと比べれば遊べる度合いは上がるが、MIMO2x2だし、アクセスポイントとしての性能は家庭用ルータと変わらないので微妙。50Eと同じ価格で出ていたらこっちを選んでもいいかも、くらい。

  • その他は須らく50Eといっしょ。やっぱりoverlayがもう少し欲しい。Fortiの純正ファームに戻す予定はないので、バックアップのファーム領域をツブしてoverlayに利用したいところだが、そうするには自分でOpenWrtにしかるべき変更を加えてビルドする必要がある。トライする気力がないのでextrootでお茶を濁すことにする。→ 先人の知恵を借りて自前ビルドをやってみた。確かに100MB超のoverlayを確保できてブラボーなのだが、やっぱりビルドには時間がかかるので頻繁にやるのはダルい。一度稼働させたらしばらくはバージョンアップしたくない感じ。結局USBメモリでのextrootに戻るかも。。

  • Realtekの8822CEカードが自宅に転がっていたので目的もなく交換してみて、普通に動いたが、送信出力がさらに低くなったこと以外には違いはなかった(当たり前)。クライアント用のカードだしな。。。OpenWrtで安定して動くmini pcieのWi-Fi 6の拡張カードが出てきたら、いずれ試してみたい。ちなみにIntelWi-Fi 6のカードは入手性がよく安価だが、APモードでは動かないらしい。残念。

 

では皆さん良いOpenWrtライフを。

 

 

 

 

OpenWrtでLuci上からシェルのコマンドを実行する方法

OpenWrtで良く使うコマンドを予め登録しておいて、Luciからワンタッチで実行できるようにする方法。PCなら普通にSSHすればいいんだけど、スマホタブレットから簡単な良くある操作をしたいときなんかにいいかも。

導入

端的にはluci-app-commandsパッケージを入れるだけ。

# opkg update && opkg install luci-app-commands

設定

Luciに入り直すとSystemsの下にメニューが増えている。

インストール直後は何も登録されていない。

ConfigureタブのAddから使いたいコマンドを登録するとこんな感じになる。

Custom argumentsをYesにすると、コマンド実行時にLuci上から引数を任意に指定できるようになる。Public accessは「認証ナシでのコマンド実行を許可する」とヘルプに書いてあるのだが、実際にどういうことなのかよく分からない。後で調べる。

登録が済んだら、Dashboardタブからコマンドを実行する。実行結果が表示される。Downloadボタンを押すとテキストファイルで実行結果が取得できる。

ちなみにCustom argumentsがYesだとこうなる。

Luci上で生シェルを使えるわけではなくて、予めコマンド登録が必要なタイプなので、使い方は若干限られそうだが、使いみち次第で色々と便利かも。

では皆さんよいOpenWrtライフを。

ThinkPad E14 Gen5のRealtek 8852CEでWi-Fi通信が引っ掛かる問題に対処したメモ

久方ぶりにノートPCを新調したんですが、Wi-Fi接続のときだけ操作に妙なラグを感じ。調べてみたら10秒おきくらいにスループットが一瞬ゼロになるという謎の症状が発覚しました。色々試して解決したので内容をメモしておきます。久々に蟹の洗礼を受けました。

環境

PC:Lenovo ThinkPad E14 Gen5 AMD
OS:Windows 11 Home 24H2
Wi-Fiアダプタ:Realtek 8852CE

お久しぶりですね蟹さん

問題

Wi-Fiでの通信が断続的に引っ掛かる。パケ詰まりみたいな感じ。大き目のファイルをダウンロードすると、10秒くらいフルスピードで通信して、3秒くらい止まって、また10秒くらい通信するというのを繰り返す。タスクマネージャーで通信レートを見ていると、規則的に途切れた山が連続する形になる。

そしてこれは通信データ量が少なくても発生する。Pingは定期的に遅れるし、SSHでLinuxサーバーに入って操作をしていると断続的に「入力したコマンドが数秒遅れて一気に表示される」という状態になる。Wi-Fi接続自体が切断されるわけではなく、データがロストしている様子もないが、10秒間隔程度で「データが詰まった」ような状態になり、3秒後にまとめて吐き出されるような利用感になる。バッファ制御なのか何なのか分からないが、非常に不愉快だし、もちろんトータルでの通信速度も下がることになる。

試したが効果がなかったこと

  • ドライバのオプションで変えられるものを一通り変更する。Multi-Channel Concurrentとかレジャーパワーセーブとか。
  • Lenovoのサイトでドライバを最新版に更新
  • HPとかDellのサイトから持ってきたドライバを使ってみる
  • Wi-Fiルータ側を別の機体にしてみる
  • 5GHzじゃなくて2.4GHzを使ってみる
  • Wi-Fiの認証方式で、WPA2とWPA3を試してみる
  • その他色んなWi-Fiルータ側のオプション変更

解決方法

MicrosoftのUpdate Catalogサイトから8852CE用の最新ドライバ(バージョン6001.16.162.1)を取得して更新する。これにより見事に改善されて、安定してスループットを持続できるようになった。パケ詰まり感覚も解消。ドライバを取得できるサイトはこちらです。

https://www.catalog.update.microsoft.com/Search.aspx?q=realtek%208852ce

ドライバに関しては当方では4つのバージョンを試してみたが、このバージョン以外のドライバではどれも解消せず。なんでやねん。

赤い枠のやつが正常動作したバージョン

追記:その後バージョン6001.16.126.333(2025/04/23)に更新しましたが、問題なく動いております。めでたし。

再追記:2026年1月時点で問題が再発。Windowsアップデートで自動的にバージョンが更新されていくのだが、またダメバージョンが適用されたらしい。納得いかん。仕方ないので手動で以前にダウンロードしておいた6001.16.162.1に戻して一旦回避。

再再追記:2026年2月のWindows Updateでまた勝手にドライバが更新されてしまったが、今回は問題は起きていない。ドライババージョンは6001.16.126.342

 

我が家にはすでに4台のノートPCと多数のスマホやタブレットデバイスがあるが、こういう症状はこのThinkPadだけ。面倒臭くなって、諦めてIntelのWi-Fiカード買って入れ替えようかと思ったけど、ドライバ更新で済みました。

しかしこの問題、パソコンの利用をスタートした直後から発生するし、Lenovoのサイトで公開されているドライバでも改善しないし、なんでこの状態で出荷されているのか謎である。不具合報告が殺到しそうなものだけど。何か特殊な発生条件があって、ヒットするユーザ数はすごく少ないのだろうか?

では皆さん、よい蟹ライフを。

 

汎発性脱毛症10周年を迎えたので体験記を書いてみる

実はわたくし全身ほとんど体毛がない人で、医学的には全身脱毛症とか汎発性脱毛症と言われる状態です。最近めでたく(?)無毛10周年を迎えました。当ブログは基本的に趣味の無線LANルーター関係のネタしか書いていないのですが、節目にあたってちょっと違ったネタをまとめておくのもいいかなと思ってこのエントリを書きました。

汎発性脱毛症とは

全身の体毛が抜ける、というか生えてこなくなる状態です。以上。シンプルですね。時間経過で多少の揺れはありますが、ピーク時(?)には本当に全ての毛がなくなります。産毛すらも消えます。毛根の活動が停止するせいか、毛穴も結構目立たなくなります。赤ん坊の肌とはまた違った独特のスベスベ感が楽しめます。私の場合は本当にそれだけで、体毛がなくなる以外の自覚症状はありません。

発症時の経緯など

30代も終わりに近づいた、とある年の冬の始めにいきなり発動しました。馴染みの床屋で「あー円形脱毛症みたいなのがありますね」と言われて気付き、ああ確かにあるな。でも近頃は健康状態もいいし、仕事のストレスもないし、公私とも生活に何の変化もないし。なんでやろ?と思っていたら、そこからスコスコと毛が抜け始め、急に頭部に大き目の円形脱毛が複数ある人になってしまいました。並行して腋毛とか陰毛も抜け始めたので、あーこりゃ頭だけじゃないなと。

で、体調は全く悪くないのですが、家族や同僚に心配され(そりゃそうだ)、確かに何か重篤な病気を抱えているサインだったらマズいので、家から比較的近くて脱毛症外来を開設している東京医科大学病院に早々に予約を取り、検査をしてもらうことにしました。血液検査、レントゲン、超音波などを一通りこなし、問診して一旦終了。

検査結果が出るまでには二週間ほどかかるのですが、私の場合は進行が早く、この間に全身の毛がほとんどなくなってしまいました。二回目の診察で見事にツルツルになった私を見て、展開の早さに先生が若干絶句するなどしましたが、何はともあれ検査では何も見つからず、健康体であるという結果に。病院の先生曰く「ぶっちゃけるとですね、脱毛症の原因って分かんないんですよ」とのこと。はい、そんな気がしてました。

何故こうなったのか

謎です。職場や職種が変わったわけでもなく、家庭の環境も同じ。引っ越しもしてないし、生活パターンも何年も一緒。過剰労働でもなく慢性的な疲労もナシ。思い当たる節も何もありません。

Webでざっくり見る限りでは、脱毛症はアトピー性皮膚炎と合併する率が高いと言われていて、実際私も結構なアトピー素因持ちです。素因というかモロに重い症状を抱えた時期が長くありました。橋本病(未発症)も抱えてますし、自己免疫が繊細なタイプなんだろうと思われます。とは言ってもアトピー歴は長いし、脱毛症状発生の前後で特に変わりがあったということもないので、アトピーと脱毛の関連の有無は謎でしかありません。現在アトピーはほぼ緩解していますが、毛はアホ毛しか生えてこないですね。まあ仮に関連が判明したとしても、それで特に何かできるわけでもないのですが。

対処とか治療は?

治療は全く何もしていません。脱毛発生直後から、一切ノーアクション。私を診てくれたドクター曰く、今の健康状態に問題はなく、何らかの深刻な病気によって脱毛が引き起こされているとは考えられない。原因は今の医学では分からない。治療の手段は一応複数あり、強いステロイドとか液体窒素塗るとか光線とか色々とあるのだけど、効果があるかどうかはやってみないと分からない。とのこと。

そして提案されたのは「急性脱毛症はやっぱり精神的な動揺があって、メンタルが参っちゃう患者さんが多いんですけど、私には、あなたはこの出来事を受け入れてらっしゃるように見えるんですね。治療にはお金も時間もかかりますし、どれだけやっても効果が出ない可能性もあります。あまり気にしていないのなら、何もしないという選択肢もありますよ」。

実際この時点で私はすでに「これはこれでまあいいか」と考えつつあったので、患者の様子を見てオープンな提案をしてくれるいい先生だなと思った記憶があります。文字通り痛くもかゆくもなく、見た目だけの話で、日々の生活には悪影響はないし、騒いでもどうにもならないし。肝っ玉の据わっているウチの嫁さんも「頭の形がユガんでなくて良かったね」とか言ってるし。アトピーが重たいときの悪夢に比べたら何てこともありません。ということで先生の言葉に従って、治療ナシを即決。健康に問題がないことが分かってスッキリした気持ちで帰宅したのでした。「オレそんなにプレッシャーかけた?なんかマズかった?」と真剣に気にしていた当時の職場の上司にはお詫び申し上げます(笑)

脱毛症の推移

さて、その後10年間が経過し、基本的には今も毛はほとんど復活はしていないのですが、ランダムなタイミングで思い出したように生えてくることがあります。思い当たる原因も規則性もなく、謎な生え方をします。パターンを列挙しておきましょう。

  • 急に眉毛が生えてきて、2か月くらいすると再びなくなる
  • 空き地に草が生えるようにパラパラと頭全体に頭髪が生えてきて、しばらくするとなくなる
  • まつ毛が下だけ生える
  • まばらに散らばって太いヒゲがアホ毛的に生える
  • 左足の中指にだけ指毛がガッツリ生える
  • 左の腋毛だけが少々生える

発毛は周期も場所も完全ランダムで、なんなら左右の対称性もありません。頭髪やヒゲは中途半端に復活されると手入れが面倒なだけなので、生えるか生えないか、どっちかにしてもらいたいところです。とはいえ全く制御できないので、何ともなりませんが。

また興味深い現象として、私の肌にはたまに結節性痒疹(デカくて長く続く発疹)が生じることがあるのですが、この痒疹の周辺に太い毛が生えてくる傾向があります。特に前腕部で顕著に発毛します。痒疹は免疫が過剰に働くことで生じる皮膚症状と言われますが、その場所の毛根が稼働を再開するというのは、果たしてどういうことなのか?うむ、分からん...

良いこともあるよ

汎発性脱毛症のメリットをGoogleで検索してみたところ、以下の結果を得ました。

いや待て。「メリットはありません」って言い切られてますが(笑)そうとも限らないです。何かと悲しみに寄った文脈で語られがちなこの現象ですが、得することもあります。最大の利点はやはり、毛に関するあらゆるメンテナンスが不要になることでしょう。皆さんは生活の中でどれだけの時間とコストを体毛の手入れに費やしているでしょうか?全身の毛がない成人男性には以下のようなボーナスが発生します。

  • 床屋に行かなくていい
  • 毎朝のヒゲ剃りがいらない
  • 鼻毛を切らなくていい
  • 眉毛を整えなくていい(これは賛否ありそうだけど)
  • 高額な費用を払って脱毛を試みる必要がない
  • 部屋のあちこちに縮れた毛を落とすこともなく部屋がキレイになる
  • 風呂で身体を洗うのが楽

タイパだコスパだと言われるこのご時世、これはもはやプラスの競争力と言っていいでしょう。さらに今どきは、金と時間と手間をかけて自らヒゲやスネ毛の永久脱毛を試みる男性が増殖しているらしいですが、こちとら無料でパーフェクトにツルツルです。朝は顔を洗うだけで終了ですから、マジで楽です。

意外なメリットをもう一つ挙げておくと、初見の人にかなりの高確率で一発で覚えてもらえるようになります。全身型脱毛症ではヒゲも眉毛もなくなり、一般的な成人型脱毛症とは違う独特のツルっとした見た目になるので、出会う人に結構なインパクトを残します。対面で会った人にはもちろん、なんならテレカンで一対多で話した場合にも効果を発揮します。私の場合は社内での認知度が明らかに高くなり、初めて組む人からも「あー知ってましたー」みたいな感じでコミュニケーションが円滑にいくようになりました。同じように、社外のお客さんにも覚えてもらえます。見本市だとかネットワーキングパーティみたいな、不特定多数の人と会って話すようなイベントでは相当な強みを発揮します。こちらも相手の顔と名前を覚えるように一層努力しないといけなくなりますが。。。

毛がないことのデメリット

よくあるデメリットはおそらく、自分の見た目の変化に対してネガティブな気持ちになること、それによって引き起こされるマイナスの影響や、治療に要する金銭や時間なのだと思います。しかし私はそこをあんまり気にしておらず治療もしていないので、恐縮ながらメンタル的なものは一旦置いておき、物理的なリスクを挙げてみましょう。

  • 目にゴミが入りやすくなる。睫毛は意外と仕事をしていた
  • 夏場に頭からの汗が目に入りやすくなる。眉毛と睫毛という二つの防波堤が存在しないため、ダイレクトにインしてくる
  • 頭部が暑さ寒さに弱くなる。真冬に帽子ナシで冷たいビル風を浴びたりすると、最悪かき氷を食べ過ぎたときのように頭がキーンとなるし、夏は夏で直射日光に耐えられない。一年を通して帽子が欠かせない
  • 頭をぶつけるとすぐ傷になる

しかしまあ、そのくらいです。クリティカルなデメリットはないです。別の言い方をすると、頭髪と睫毛と眉毛以外の毛は何ら仕事をしていないということです。特に鼻毛よ、お前のことだ。

汎発性脱毛症の私の解釈

何度か触れたとおり、私は「毛がないならまあそれでもいいか」と思っていて、治療を試す気も全然ありません。しかし何故なのか。10周年のこの機会に言語化を試みてみます。

それほど悪くないと思っている

完全スキンヘッドで眉毛もないわけですが、まあでも慣れればそれほど悪くないと思うんですよ。清潔感もなくもないし。太いフレームのメガネとか相性いいですよ。ワンパンマンのサイタマっぽいと言えないこともない。かも。

スッキリしてサッパリする

これは自分でも意外でしたが、体毛がないことでかなりのスッキリ感があります。特にスネ毛、腕毛、腋毛、ヒゲが生えてこないことは、もはや爽快と言っていい感覚。美容整形で永久脱毛を試みる男性諸君の気持ちもちょっと分かるようになりました。

肉体的な苦痛がない

脱毛症には痛みとか痒みはありません。疲労や倦怠感もないし、睡眠が妨げられることもありません。風呂にも楽しく入れます。運動も普通にできて、健康に生活できます。かつて重症アトピーで辛酸を舐めた経験からすると、全然つらいことなんかないなと。

メンテナンスフリー

これはすでに述べました。とにかく楽で手間がかかりません。ある意味では人類の進化の一形態のような気もします(笑)

誰も気にしていない

脱毛症に限ったことではないですが、毛がなくても特に誰からも気にされません。人間関係に悪い影響が出ることもなく、仕事も変わらずできます。特に近頃はルッキズム批判の風潮もあるせいか、揶揄するような態度を取られることも皆無です。まあこれに関しては、私は結構歳をとり、価値観や評価軸がある程度出来上がっていたところからの脱毛症だったために色々と達観できた、というところはあるでしょう。若い頃だったらもうちょっと迷っていたかもしれません。

家族の理解

この状態を当たり前のこととして普通に受け入れてくれている嫁さんに感謝。

対策が面倒でやる気にならない

私は生来のモノグサです。トライアンドエラー的な治療に時間とコストをかけるのは全く性に合いません。アトピーが重いときはそんな余裕コイたことは言ってられませんでしたが、脱毛症に関しては自分に切迫感がないのでモチベーションが湧きません。この注射を一本打てばフサフサに戻るよ、みたいなお手軽な新薬が出たら試してみてもいいですが(笑)

見た目でカバーする方向の対処についても同じような考え方です。ウィッグは扱いが面倒だし、一度始めるとずっと続けることになりそうだし。何よりも頭皮がかゆくなるようなので、アトピーの気がある私には全く向かないソリューションですね。眉毛を描くのも何か違うし。何もせず、毛がないことで得られたメンテフリーのメリットを最大限に享受する路線が自分にとっては合っているように思います。

何なら病気だと思ってない

アバターを変えてみました。くらいの気持ち。

まとめ

「私は気にしてません」の一言で済みそうな話を分解して長々と書いてみました。特にオチはないんですが、こういう汎発性脱毛症の人間もいますよ、ということで。誰かの何かの参考になれば嬉しく思います。