35歳からの中二病エンジニア

社寺・鉄道・アニメを愛でるウェブ技術者の呟き

Windowsのスリープ復帰時にテレビ電源を連動させるのが難しかった件

結論から先に言うと、Windowsのタスクスケジューラやスリープ復帰周りには罠がいっぱいなので、特にログオン状態以外で利用したい時には注意されたいという話である。

事の背景

今の主力PCは、ディスプレイにテレビ(BRAVIA KJ-43X8500G)を使っている。

テレビのHDMIには機器間操作の規格としてHDMI-CECというものがあり、消費者向けにはブラビアリンク等の各社テレビ向けの愛称が付けられていることが多い。テレビのリモコンでブルーレイレコーダーを操作したり、プレイステーションの電源とテレビの電源が連動するのにも、この仕組みが利用されている。

ところが、今の所PC側でのHDMI-CEC対応というのはごく限られたメーカー製PCだけに留まっていて、今後も広がる気配が無い。であれば電源連動タップはどうかとも考えたくなるけれども、今時のテレビは主電源を切ってしまうと再起動するのに結構な時間が掛かるので、現実的ではない。そもそも通電しても改めて電源スイッチをオンにする必要がある機種が大半ではないかと思われる。

というわけで、電源連動のためには各々知恵を絞る必要がある。幸い最近のBRAVIAREST APIで電源も含めた各種操作が可能となっているので、今まではAlexaスキルを自作して、WoLによるPC起動とこのAPIへのリクエストを同時に行うことで、電源連動を実現していた。

ただ、どうにも最近は「Alexa、PCを起動して」と発生するのが面倒になってきて、キーボードやトラックパッドを弄るだけで何とかならないかと思うようになってきた。というわけで、今回目を付けたのがWindowsのタスクスケジューラだ。

設定の手順

罠にさえハマらなければ、スリープ復帰時にBRAVIAAPIを叩いて電源をオンにするのは難しくない。手順はこうだ。

  1. 適当なタスクを作成する
  2. [全般] の設定を変更する
    • ユーザーがログオンしているかどうかにかかわらず実行する を選択
    • 最上位の特権で実行 をチェック
    • 表示しない をチェック
  3. [トリガー] の設定を追加する
    • [ログ] は システム を選択する
    • [ソース] は Power-Troubleshooter を選択する
    • [イベントID] は 1 を入力する
    • 遅延時間を指定する をチェックして 5秒間 に設定する
  4. [操作] の設定を追加する
    • [プログラム/スクリプト] に %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe を指定する
    • [引数の追加] に -Command [スクリプトのパス] を入力する
    • [開始] にスクリプトディレクトリーを入力する
  5. [条件] の設定を変更する
    • コンピューターをAC電源で使用している場合のみタスクを開始する のチェックを外す

なお、上記で指定したスクリプトのパスに、以下のスクリプトを用意する必要がある。また、事前にBRAVIAのIPコントロールを有効化し、認証設定をする必要があるが、その辺りはDevelopersIOの記事が詳しい。

$uri = 'http://[BRAVIAのIPアドレス]/sony/system'
$headers = @{
  'X-Auth-PSK' = "[BRAVIAのPre-Shared Key]"
}
$body = @{
  method = 'setPowerStatus'
  id = 55
  params = @(
    @{
      status = $true
    }
  )
  version = '1.0'
} | ConvertTo-Json -Compress
Invoke-WebRequest -Headers $headers -Method 'POST' -Uri $uri -Body $body -UseBasicParsing

ハマり所

  • スクリプトをネットワークドライブに置くと、ログオン前にはアクセスできない
  • NICの電源管理の設定で、 電力の節約のために、コンピューターでこのデバイスの電源をオフにできるようにする を外しておかないとAPIにリクエストできない
  • NICの設定ができていても、遅延時間を5秒以上取らないとAPIにリクエストできない
  • [プログラム/スクリプト] にスクリプト本体を指定すると実行できない

あと、僕の環境ではPowerShellを管理者権限で実行可能にしてあるためその辺は問題無かったが、ひょっとするとデフォルト状態だと管理者権限周りも設定を弄る必要があるかもしれない。あと、Windows使いの開発者であれば大丈夫だとは思うが、自分のユーザーアカウントが管理者権限でない場合も色々面倒な気がする…。

ちなみに、僕はスクリプトをWSL配下に設置していたり、遅延時間を設定していなかったりというあたりでドハマリしたけれども、これを全部一発スルーできる猛者がいたら凄いと思う。

おわりに

スリープ復帰から5秒待たないといけないという残念さはありつつも、何とか目的は達成できた。ただ、Windowsはこの手の罠が色んな所に潜んでいるので、そこも含めて楽しめる変態ドMなユーザーでないと、ディープに活用するのは大変だろうなという気はする。