自室にデジタルサイネージを作ろう

職場等で、大型のディスプレイに予定やお知らせを表示している、いわゆるデジタルサイネージ。

ああいう感じで、直近の勤務予定とか、天気予報とか、ちょっとしたメモ書きなどを自分の部屋にも常に表示しておきたいと思った。

完成したもの

先に結論から書くと、こんなものを作った。

基本的には、単に適当なWindows PCで必要な情報を表示させているだけである。

右側の天気予報はWindowsのストアアプリ「そら案内」を表示させている。このアプリはもともとタブレットでの表示を想定しているためか、大き目に表示されるのでこういう用途にピッタリである。

左下のホワイトボードのような手書きのメモについては、OneNoteにサイネージ表示専用のページを作って、これにiPadで書き込むというやり方をとっている。リアルタイムで反映されるのでこれが割と便利。

既製品で対応できなかったのは、日付と時刻の表示と、その下に表示している3日分の勤務予定の表示。これは自作のアプリケーションを使用している(後述)。

自分で作ったもの

特に勤務予定の表示は、勤務表を格納するデータベース(MySQL)を用意するなど、多少手間をかけた。

勤務に合わせてディスプレイの電源を自動で制御

もう一つ、このシステムで工夫しているのは、出勤・帰宅時間や就寝時間に合わせて、不要な時間はディスプレイの電源を自動でON/OFFする仕組みを作った点。

私の仕事はシフト勤務のため、日によって出勤時間が異なり、休日も一定の曜日に定まっていない。そのため、毎日決まった時間にディスプレイをON/OFFするという単純な制御ではなく、もう少し複雑な制御が必要になる。

これには、勤務情報のデータベースに出勤時間と帰宅時間を持たせ、これを参照して動的に電源制御をおこなうことで対応している。

電源制御用のプログラムはC#で作ったが、C#(というか、.NET framework)にはディスプレイの電源を直接制御できる機能はないようなので、内部的にWin32 APIを直接呼び出す処理を行う必要がある。

この辺はググれば先人の知恵がいろいろと出てくるので、ありがたく参考にさせてもらった。

Windowsアプリ動作中スタンバイ防止、ディスプレイオフ(SetThreadExecutionState、SC_MONITORPOWER)
Windowsアプリが動いている間、Windowsがスタンバイ状態にならないようにしつつ、ディスプレイをオフにしたくて、やってみたメモです。 調べてみたら割とすぐ出てきたので、わざわざメモするほどではないかもしれないけど。 C#で作っていますが、Windows APIを呼ぶだけなので、どの言語でも実現方法は同じです。...

ただ、私の環境ではディスプレイの電源ONをSendMessage関数で行っても、一瞬電源が入るが、再び切れてしまうという動作が発生し、期待通りの動作にはならなかった。

これには、プログラムからマウスを動かすことで強制的にディスプレイのスリープを解除するというやり方で対処。 こちらも先人の知恵を拝借した。

スクリーンセーバ抑止PowerShell - Qiita
やりたい事 スクリーンセーバうざい 制約 Windows10 外部ソフト持ち込まない できた PowerShell 多分PowerShell2=Win7以降使えると思う 外見はbat 内部はC# マ...

コードは以下のように多少改変。中身は流用なので詳しくは解説しない。

using System;
using System.Runtime.InteropServices;

namespace DisplayPowerController
{
    class Mouse
    {
        [DllImport("user32.dll")]
        static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

        [StructLayout(LayoutKind.Sequential)]
        struct INPUT
        {
            public int type;
            public MOUSEINPUT mi;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public uint mouseData;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        public static void Move()
        {
            INPUT input = new INPUT();
            input.type = 0;
            input.mi = new MOUSEINPUT
            {
                dwExtraInfo = IntPtr.Zero,
                dx = 0,
                dy = 0,
                time = 0,
                mouseData = 0,
                dwFlags = 0x0001
            };
            int cbSize = Marshal.SizeOf(typeof(INPUT));
            _ = SendInput(1, ref input, cbSize);
        }

    }
}

呼び出し元で、以下のようにメソッドを呼び出せば、ディスプレイの電源が入る。

Mouse.Move();

ちなみに、マウスカーソルの座標移動は.NETのSystem.Windows.Forms.Cursor.Positionプロパティも使えるようだが、これだとディスプレイのスリープ解除はできないようだ。結局、Win32 APIの操作が必要。

おまけ

今回使っているディスプレイは、中古で購入したEIZOのFlexScan S1703。約3,500円。

24インチのディスプレイも余ってはいるのだが、部屋の片隅に置いておくにはちょっと大きすぎるので、あえて17インチのディスプレイを選択。結果的には、表示させたい内容がぴったり収まって、ちょうどよい選択だった。

製造年は2015年で、使用時間は1万2000時間越えと、それなりに酷使された機体のようだった。

その割には発色もよく、表示が暗いということもない。この点はLEDバックライトの強みだと思う。中古でディスプレイを購入する場合は、LEDバックライトのものを選ぶことをお勧めする。

コメント

  1. 和也 より:

    現在日時を画像のように表示するのもMySQLというものを使ってらっしゃるのでしょうか?

    • ちりつもん より:

      コメントありがとうございます。
      MySQLは勤務予定のデータを格納するためのデータベースとして使っています。
      現在日時の表示自体は.NETのWPFアプリケーションですね。

タイトルとURLをコピーしました