【実機解説】SQL Serverに溜めたPLCデータを、Grafanaでリアルタイム監視ダッシュボードにする方法

fa-engineer

導入:結論から先に

SQL Serverに溜めたPLCのデータは、Grafana(グラファナ)を使えば、リアルタイムで動く監視ダッシュボードにできます。しかも全部無料です。

このシリーズでは、これまでFANUCロボットの電流値・位置座標をPLCで常時取得する方法、そしてそのデータをPythonでSQL Serverに自動保存する方法を解説してきました。

データが溜まると、次に来るのはこの疑問です。

溜めたはいいけど、どうやって見るのか?

SSMSで表を眺めても、数字の羅列では異常に気づけません。グラフにして初めて「いつもと違う」が見えるようになります。この記事では、無料のGrafanaでその環境を作ります。

  • 完全無料(Grafana・SQL Server Express、共有も無料)
  • 数秒ごとに自動更新されるリアルタイム監視画面
  • しきい値を超えたら一目でわかるグラフ

この記事で作る画面がこちらです。緑が正常な設備、黄色が電流値の上がっている設備。赤い線がしきい値(4.5A)です。

この記事で使う環境

役割ソフト費用
データベースSQL Server 2022 Express(前回構築済み)無料
可視化ツールGrafana 13無料
対象データロボットの電流値・座標(robot_logテーブル)

SQL Server側の構築がまだの方は、前回の記事を先にご覧ください。この記事はその続きです。

ステップ1:Grafanaをインストールする

Grafana公式サイトからWindows版のインストーラーをダウンロードします。

👉 Grafana公式:ダウンロードページ(Windows)

OSS版(無料版)のインストーラー(.msi)を実行し、画面の指示に従うだけです。インストールが完了すると、GrafanaはWindowsのサービスとして自動起動します。

ブラウザで http://localhost:3000 を開くとログイン画面が出ます。初期のユーザー名・パスワードはどちらも admin で、初回ログイン後に新しいパスワードの設定を求められます。

Grafanaのログイン画面

つまずきポイント:パスワードを忘れたら
「パスワードを忘れた場合」からメールを送ろうとしても、メール送信の設定をしていないと届きません。その場合は管理者権限のPowerShellで次の3行を順に実行すればリセットできます(Grafanaがデータベースを使用中だと失敗するので、いったんサービスを止めるのがコツです)。

Stop-Service Grafana

& "C:\Program Files\GrafanaLabs\grafana\bin\grafana.exe" cli --homepath "C:\Program Files\GrafanaLabs\grafana" admin reset-admin-password "新しいパスワード"

Start-Service Grafana

ステップ2:SQL Server側の準備(3つ)

ここがこの記事で一番大事なパートです。GrafanaからSQL Serverに接続するには、SQL Server側に3つの準備が必要です。

準備なぜ必要か
混合モード認証Grafanaは専用のSQLアカウントで接続するため。Windows認証のみでは繋げない
TCP/IP通信を有効化Grafanaはネットワーク経由で接続する。SQL Server Expressは初期状態でTCP/IPが無効
読み取り専用ユーザー可視化ツールに書き込み権限は不要。閲覧だけに絞るのが実務の鉄則

SSMSの「新しいクエリ」で、次のSQLを実行します(パスワードはご自身で決めたものに変えてください)。

-- ① 混合モード認証を有効化(SQLアカウントでのログインを許可)
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', REG_DWORD, 2;

-- ② TCP/IP通信を有効化+固定ポート1433に設定
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp', N'Enabled', REG_DWORD, 1;
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp\IPAll', N'TcpPort', REG_SZ, N'1433';
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp\IPAll', N'TcpDynamicPorts', REG_SZ, N'';

-- ③ Grafana用の「読み取り専用」ユーザーを作成
CREATE LOGIN grafana_reader WITH PASSWORD = 'ここにパスワード', CHECK_POLICY = OFF;
USE plc_iot;
CREATE USER grafana_reader FOR LOGIN grafana_reader;
ALTER ROLE db_datareader ADD MEMBER grafana_reader;   -- 閲覧のみ。書き込み・削除は不可

実行後は必ずSQL Serverを再起動してください。①②は再起動して初めて有効になります。SSMSの左ツリーでサーバー名を右クリック →「再起動」が簡単です。

読み取り専用にする意味db_datareader は「SELECTだけ許可」のロールです。仮にGrafana側の設定が漏れても、データを書き換えられたり消されたりする心配がありません。可視化ツールを繋ぐときの基本作法です。

ステップ3:GrafanaからSQL Serverに接続する

Grafanaの画面で、左メニューの「Connections」→「Data sources」→「Add new data source」と進み、「Microsoft SQL Server」を選びます。設定内容は次のとおりです。「この値の出どころ」列を確認して、ご自身の環境に合わせて読み替えてください(そのまま真似するのではなく、ステップ2で作成したものと一致させます)。

項目入力する値この値の出どころ
Hostlocalhost:1433SQL Serverが動いているPCとポート。Grafanaと同じPCならこのまま。別PCならそのIPアドレス(例:192.168.0.50:1433
Databaseplc_iotステップ2で作成したデータベース名(前回記事で作ったもの)。別の名前にした方はご自身の名前に
AuthenticationSQL Server Authentication固定。ステップ2で混合モードにしたのでこれを選ぶ
Usergrafana_readerステップ2で作成した読み取り専用ユーザー名。変更した方はその名前に
Password(各自の値)ステップ2でご自身が決めたパスワード
暗号化(Encrypt)disable(無効)固定。ここが重要(理由は下記)

暗号化の設定に注意
ここを既定のままにすると「証明書が信頼できない」というエラーで接続できません。自分のPC内だけの通信なので disable(無効) で問題ありません。
なおブラウザの日本語自動翻訳をONにしていると、選択肢の false が「間違い」と誤訳されて表示されます。意味が通じず混乱するので、Grafanaは翻訳をOFF(英語表示)で使うことを強くおすすめします

入力できたら一番下の「Save & test」をクリック。緑色で「Database Connection OK」と出れば成功です。

ステップ4:グラフを作る(ここに2つの罠)

ダッシュボードを新規作成し、パネルを追加してデータソースにmssqlを選びます。クエリ欄は「Code」モードに切り替え、「Format」を「Time series」に設定します。

そして、貼り付けるSQLがこちらです。

SELECT
  time_utc AS time,
  equipment_name AS metric,
  current_j1 AS value
FROM (
  SELECT
    DATEADD(hour, -9, r.recorded_at) AS time_utc,
    e.equipment_name,
    r.current_j1
  FROM robot_log r
  JOIN equipment e ON e.equipment_id = r.equipment_id
) AS t
WHERE $__timeFilter(time_utc)
ORDER BY time_utc

このSQLには、実際に私がハマった2つの落とし穴への対策が入っています。順に説明します。

時刻が9時間ズレる(UTCの問題)

設定は合っているのに「No data」しか出ない——最初にぶつかったのがこれでした。

原因はタイムゾーンです。Grafanaは表示期間を必ずUTC(世界標準時=日本より9時間前)でデータベースに問い合わせます。ところが前回の記事では、Pythonの datetime.now()(=日本時間)で保存していました。

時刻
Grafanaが問い合わせる範囲15:41〜21:41(UTC)
データベースに入っている値03:29〜06:29(日本時間)
結果該当0件 → No data

そこで DATEADD(hour, -9, r.recorded_at) で日本時間から9時間引き、UTCに変換しています。Grafanaは表示時に自動で日本時間へ戻すので、グラフの目盛りは正しく日本時間で表示されます
-9日本時間(JST)の場合の時差です。他のタイムゾーンの環境では、その地域の時差に読み替えてください。

本来の正解は「最初からUTCで保存する」ことです。Python側を datetime.now() から datetime.now(timezone.utc)(UTCで取得)に変えておけば、この変換自体が不要になります。※ datetime.utcnow() はPython 3.12以降で非推奨のため使いません。これから作る方はUTC保存を強くおすすめします。上記の変換は、すでに動いているシステムを変更できない場合の現実解です。

$__timeFilter に関数を入れてはいけない

これが最も気づきにくい罠でした。時刻のズレに気づいた私は、最初こう書きました。

-- ❌ これは動きません
WHERE $__timeFilter(DATEADD(hour, -9, r.recorded_at))

一見正しそうですが、エラーも出ないのに結果は0件。原因はGrafanaが生成した実際のSQLを見て判明しました。

-- Grafanaが生成したSQL(壊れている)
WHERE DATEADD(hour BETWEEN '2026-07-21T15:43:55Z' AND '2026-07-21T21:43:55Z')

$__timeFilter() は、カッコの中を「最初のカンマまで」しか列名として認識しません。そのため DATEADD(hour だけを取り出して置換してしまい、SQLが壊れていたのです。

対策はサブクエリで先に変換を済ませ、$__timeFilter() には列名だけを渡すこと。先ほどのSQLがその形になっています。

覚えておくと一生使える切り分け方
「設定は合っているのにデータが出ない」ときは、Query inspector(クエリ欄の右にあるボタン)を開いてください。Grafanaが実際に投げたSQLが見られます。エラーが出ないタイプの不具合は、これを見ないと永久に気づけません。

ステップ5:監視ダッシュボードに仕上げる

グラフが出たら、右側の設定パネルで仕上げます。ここを整えるだけで、一気に「監視画面」らしくなります。

  • Panel options → Titleロボット電流値(J1軸) など分かりやすい名前に
  • Standard options → Unitamp で検索して Ampere (A) を選択(縦軸に単位が付く)
  • Thresholds:既定の 804.5 に変更(異常とみなす電流値。この値は設備ごとに、正常運転時の最大値に余裕を足して決めます。今回は例として4.5Aとしています)
  • Graph styles → Show thresholdsAs lines を選択 ← これを忘れると赤線が描かれません

Thresholdsに値を入れただけでは線は出ません。「Show thresholds」を「As lines」にして初めて赤い水平線が引かれます。ここは分かりにくいので注意してください。

リアルタイム更新にする

最後に、画面右上の更新間隔(「Refresh」ボタンの隣)をクリックし、「5s」や「10s」を選びます。これで数秒ごとにグラフが自動更新され、現場のモニターに映しっぱなしにできる監視画面が完成します。

設備の値が変化すると、グラフの右端がリアルタイムで伸びていきます。しきい値を超えた設備は赤線の上に出るので、数字を読まなくても「異常が起きている」と分かります。これがダッシュボードの価値です。

つまずきポイントまとめ

今回の構築で実際に遭遇したものを、症状別にまとめます。

症状原因対処
接続できない(証明書エラー)暗号化設定が既定のままEncrypt を disable(無効)
選択肢が「間違い」と表示されるブラウザ翻訳が false を誤訳翻訳をOFFにして英語表示で使う
No data(データが出ない)GrafanaはUTCで問い合わせるUTCで保存するか、DATEADD(hour,-9,…) で変換
エラーは出ないが0件$__timeFilter() に関数を入れたサブクエリで変換し、列名だけを渡す
しきい値の赤線が出ないShow thresholds が OffAs lines を選択
グラフが動いて見えない表示期間が広すぎるLast 5 minutes など短い期間にする

【締め】これで「取る→溜める→活かす」がつながった

シリーズを通して、設備IoTの一連の流れが完成しました。

FANUCロボット(電流値・座標)
   │  ① プロトコルスタジオで常時取得
   ▼
Keyence PLC(DMデバイスに保持)
   │  ② Pythonで読み出してINSERT
   ▼
SQL Server(robot_logに蓄積)
   │  ③ Grafanaが読み取り専用ユーザーで参照
   ▼
リアルタイム監視ダッシュボード ← 今回はここ

ここまで来ると、次のような発展が現実的に見えてきます。

  • アラート通知:Grafanaにはしきい値超過をメールやSlackに通知する機能があります
  • 複数設備の一覧監視:設備リストとリレーションを組んであるので、設備が増えてもグラフの系列が自動で増えます
  • 長期傾向の分析:同じデータを日単位・月単位で見れば、劣化の進行が見えてきます

今回のダッシュボードで設備ごとに色分けされたグラフが自動で出せたのは、前回の記事で「設備リスト」と「データ収集」を設備IDでリレーションしておいたおかげです。最初のテーブル設計が、こういうところで効いてきます。

データは「取る」だけでは価値になりません。溜めて、見える形にして、初めて判断材料になります。この流れを一気通貫で構築できるのが、FA-Tech Labの強みです。

関連記事

お問い合わせ

「設備の稼働状況をリアルタイムで見える化したい」「PLCのデータを収集・監視する仕組みを作りたい」

そんなご相談を承っています。PLC側の設定から、データベース設計・蓄積・可視化まで一気通貫で対応できます。お気軽にお問い合わせください。

ABOUT ME
Yu
Yu
設備エンジニア(フリーランス)
生産技術の現場で10年以上の経験を持ち、制御設計を中心に生産設備の開発全般に携わってきました。 特に、産業用ロボットを活用した自動化設備の開発を得意としており、機械・電気・制御の知識を横断的に活かして業務に取り組んでいます。 近年では、PLCと連携したIoTシステムの構築にも注力しており、PythonやSQL Serverなどを活用したデータ収集・可視化・分析の仕組みづくりにも対応しています。 現場のリアルな課題を解決するための実践的なノウハウを発信していきます。
記事URLをコピーしました