# 運用・管理 / MODBUS

MODBUSは、工場、インフラなどのオートメーションシステム(*) において、監視用端末が制御装置、測定機器、センサーなどの産業用電子機器から情報を収集したり、それらの機器に指示を出したりするために用いられる産業用通信プロトコルです。
(*) このような監視・制御システムをSCADA（Supervisory Control And Data Acquisition）システムと呼びます。MODBUS関連コマンドのキーワード「scada」はこれに由来しています。
本製品はMODBUS TCPのサーバー機能（監視・制御される側の機能）をサポートしているため、産業用ネットワークに組み込んで、監視用端末からスイッチポートの情報を取得したり、設定を変更したりすることができます。

## MODBUSの概要

MODBUSは、クライアント（監視用端末。マスターともいう）がサーバー（産業用電子機器。スレーブともいう）に要求（コマンド）を送り、サーバーがこれに応じた動作を行ってクライアントに応答を返す、シンプルなリクエスト・レスポンス型のプロトコルです。MODBUSにおいて動作を開始できるのはつねにクライアント（マスター）であり、サーバー（スレーブ）はクライアントから要求を受けたときだけ動作を行います。
MODBUSプロトコルには、シリアル回線用のMODBUS RTU、MODBUS ASCIIと、TCP/IPネットワーク上で使用するためのMODBUS TCPがあります。本製品がサポートしているのはMODBUS TCPです。

## 本製品の仕様

- MODBUS TCPサーバー機能を実装（IPv4/IPv6両対応）。
- クライアントからの下記要求（コマンド。ファンクションコード）に応答。これら以外のコマンドは未サポート。
  - 03 (Read Holding Registers) - 読み書き可能なレジスター（情報）の読み出し（本製品の設定や状態を取得する）
  - 04 (Read Input Registers) - 読み出しのみ可能なレジスター（情報）の読み出し（本製品の設定や状態を取得する）
  - 06 (Write Holding Registers) - 読み書き可能なレジスター（情報）に対する書き込み（本製品の設定や状態を変更する）
- 前記コマンドによりクライアントからアクセス・変更可能な情報の一覧は、別掲のレジスターマッピングを参照。
- VCS構成でも使用可能。VCSメンバーIDはMODBUSパケットのUnit IDフィールドを使って指定する（Unit ID = 0 はVCSマスターを指す）。
  - VCSマスター切り替え時、統計情報は保持される。
  - VCSマスター切り替え時、クライアントの接続はいったん切断される。

## 基本設定

初期状態ではMODBUS TCPサーバー機能は無効です。
また、MODBUSサーバー機能を利用するためには、MODBUSクライアントから接続可能なIPアドレスを本製品に設定しておく必要があります。以下の説明では、本製品のIPアドレスは設定済みであると仮定しています。

1. MODBUS TCPサーバーを有効にするには、scada modbus tcp serverコマンドを実行します。

       awplus(config)# scada modbus tcp server

2. MODBUSには認証機能がないため、初期状態では本製品に到達できるすべてのホストが本製品のMODBUS TCPサーバーに接続してコマンドを発行できます。
   MODBUS TCPサーバーへの接続を指定したIPv4/IPv6アドレスからだけに限定するには、scada modbus tcp server access permitコマンドを使います。

       awplus(config)# scada modbus tcp server access permit 192.168.10.3

3. MODBUS TCPサーバーを有効にしても、初期状態では情報の読み出しのみが可能で、書き込み（設定値や状態の変更）はできません。
   書き込みが必要な場合は、scada modbus tcp server accessコマンドでread-writeを指定してください。

       awplus(config)# scada modbus tcp server access read-write

   Note

   書き込みを許可した場合はMODBUSクライアントから本製品の設定変更が可能になりますので、手順2で述べたscada modbus tcp server access permitコマンドやその他のトラフィック制御機能を利用して、クライアントからのアクセスを限定することをおすすめします。

MODBUS TCPサーバーは初期設定でポート502番を使います。別のポートを使用するには、scada modbus tcp server portコマンドを実行します。

    awplus(config)# scada modbus tcp server port 30502

MODBUS TCPサーバーへの同時接続数は初期状態で1つだけに制限されています。同時接続数を変更するには、scada modbus tcp server connectionコマンドを使います。

    awplus(config)# scada modbus tcp server connection 5

MODBUS TCPサーバーの設定と統計情報はshow scada modbus tcp serverコマンドで確認できます。

    awplus# show scada modbus tcp server

MODBUS TCPサーバーの統計情報をクリアするにはclear scada modbus tcp server statisticsコマンドで確認できます。

    awplus# clear scada modbus tcp server statistics

接続中のクライアントの情報は show scada modbus tcp server connectionsコマンドで確認できます。

    awplus# show scada modbus tcp server connections

接続中のクライアントを強制切断するには clear scada modbus tcp server connectionコマンドを使います。

    awplus# clear scada modbus tcp server connections 192.168.10.3 51002

## レジスターマッピング

本製品のMODBUS TCPサーバーは、下記の表に示すレジスター（情報）をサポートしています。
[表の読み方]

- 下記表はAlliedWare Plus製品の共通仕様です。
  そのため、ご使用の機種ではサポートされていない機能に関するレジスターを含む場合があります。
- サポートしていない機能（アラーム、PoEなど）に関するレジスターを読み出した場合はつねに0が返ります。
  また、サポートしていない機能に関するレジスターに書き込んだ場合は何も起こりません。
- データ読み出し用のMODBUSコマンド「03 Read Holding Registers」、「04 Read Input Registers」では、取得対象レジスターの開始アドレスとサイズを指定します。
- データ書き込み用のMODBUSコマンド「06 Write Holding Registers」では、変更対象レジスターの開始アドレスと書き込むデータを指定します。
- 各レジスターの開始アドレスとサイズは、下記表の「アドレス」、「サイズ」欄で確認できます。MODBUSにおける「1 ワード」は16ビット（2バイト）を表します。
- 各レジスターのデータ型と意味は、下記表の「データ型」、「意味」で確認できます。データ型には次のようなものがあります。
  - UINT - 符号なし整数
  - HEX - バイト（バイナリー）列
  - ASCII - ASCII文字列
  - ENUM - 列挙型整数
  - FLOAT - 浮動小数点数
  - BOOL - 真偽値
- 下記表の「アクセス権」が「R」のレジスターは読み出し専用（Input Register）、「R/W」のレジスターは読み出しと書き込みが可能（Holding Register）です。ただし書き込みは、scada modbus tcp server accessコマンドで明示的にread-writeを設定しない限り拒否されます。

表 1：本製品のMODBUSレジスターマッピング
アドレス（16進） | サイズ | データ型 | アクセス権 | 意味
VCSグループ全体のシステム情報
0x0000 | 1 ワード | UINT | R | マッピングバージョン
0x0001 | 32 ワード | ASCII | R | システム名
0x0021 | 32 ワード | ASCII | R | ソフトウェアバージョン
0x0041 | 3 ワード | HEX | R | VCSグループのMACアドレス
0x0044 | 1 ワード | HEX | R | VCSメンバー構成のビットマップ。下位ビットから順にスタックメンバーID=1～8の有無を表す
0x0045 | 1 ワード | UINT | R | VCSグループ内の合計ポート数
0x0046 | 1 ワード | UINT | R | VCSグループ内の合計障害（Fault）数
0x0047 | 1 ワード | UINT | R | VCSグループ内の合計センサー数
0x0048 | 1 ワード | UINT | R | VCSグループ内の合計アラーム数
0x0049 | 1 ワード | UINT | R/W | スタックメンバー別アラーム出力のサポート有無
0x004A | 2 ワード | UINT | R | TCP接続アップタイム。読み出し要求を受信したTCPコネクションの持続時間（秒）を示す
0x004C | 1 ワード | HEX | R/W | マスターハートビート時間（秒）（最大値255）
0x004D | 1 ワード | HEX | R | スレーブハートビート
VCSグループ全体のアラームモニタリング情報
0x0080 | 1 ワード | ENUM | R | アラーム#1の種別
0x0081 | 2 ワード | HEX | R/W | アラーム#1の設定（出力先メンバーID 1～4）
0x0083 | 2 ワード | HEX | R/W | アラーム#1の設定（出力先メンバーID 5～8）
0x0085 | 1 ワード | BOOL | R | アラーム#1の状態 0x0000=クリア 0xFFFF=セット
0x0086 | 1 ワード | ENUM | R | アラーム#2の種別
... これ以降、アラーム#2～16までの情報が続く
0x00DA | 1 ワード | ENUM | R | アラーム#16の種別
0x00DB | 2 ワード | HEX | R/W | アラーム#16の設定（出力先メンバーID 1～4）
0x00DD | 2 ワード | HEX | R/W | アラーム#16の設定（出力先メンバーID 5～8）
0x00DF | 1 ワード | BOOL | R | アラーム#16の状態
スタックメンバーXのシステム情報（メンバーID「X」はUnit IDで指定）
0x0120 | 1 ワード | UINT | R | スタックメンバーXの合計ボード数
0x0121 | 1 ワード | UINT | R | スタックメンバーXのポート数
0x0122 | 1 ワード | UINT | R | スタックメンバーXの障害（Fault）数
0x0123 | 1 ワード | UINT | R | スタックメンバーXのセンサー数
0x0124 | 1 ワード | UINT | R | スタックメンバーXのアラーム数
スタックメンバーXの製品（部品）情報（メンバーID「X」はUnit IDで指定）
0x0200 | 1 ワード | ENUM | R | 製品（部品）#1の種別
0x0201 | 1 ワード | UNIT | R | 製品（部品）#1のスロット番号
0x0202 | 32 ワード | ASCII | R | 製品（部品）#1の名称
0x0222 | 32 ワード | ASCII | R | 製品（部品）#1のシリアル番号
0x0242 | 3 ワード | HEX | R | 製品（部品）#1のMACアドレス
0x0245 | 1 ワード | ENUM | R | 製品（部品）#2の種別
... これ以降、製品（部品）#2～32までの情報が続く
0x0A9D | 3 ワード | HEX | R | 製品（部品）#32のMACアドレス
スタックメンバーXのセンサー情報（メンバーID「X」はUnit IDで指定）
0x1000 | 1 ワード | ENUM | R | センサー#1の種別
0x1001 | 2 ワード | FLOAT | R | センサー#1の読み取り値
0x1003 | 1 ワード | ENUM | R | センサー#1の単位
0x1004 | 1 ワード | UINT | R | センサー#1の障害（Fault）ステータス
0x1005 | 1 ワード | ENUM | R | センサー#2の種別
... これ以降、センサー#2～128までの情報が続く
0x127B | 1 ワード | ENUM | R | センサー#128の種別
0x127C | 2 ワード | FLOAT | R | センサー#128の読み取り値
0x127E | 1 ワード | ENUM | R | センサー#128の単位
0x127F | 1 ワード | UINT | R | センサー#128の障害（Fault）ステータス
スタックメンバーXのアラームモニタリング情報（メンバーID「X」はUnit IDで指定）
0x3000 | 1 ワード | ENUM | R | アラーム#1の種別
0x3001 | 2 ワード | HEX | R/W | アラーム#1の設定（出力先メンバーID 1～4）
0x3003 | 2 ワード | HEX | R/W | アラーム#1の設定（出力先メンバーID 5～8）
0x3005 | 1 ワード | BOOL | R | アラーム#1の状態 0x0000=クリア 0xFFFF=セット
0x3006 | 1 ワード | ENUM | R | アラーム#2の種別
... これ以降、アラーム#2～128までの情報が続く
0x32FA | 1 ワード | ENUM | R | アラーム#128の種別
0x32FB | 2 ワード | HEX | R/W | アラーム#128の設定（出力先メンバーID 1～4）
0x32FD | 2 ワード | HEX | R/W | アラーム#128の設定（出力先メンバーID 5～8）
0x32FF | 1 ワード | BOOL | R | アラーム#128の状態
スタックメンバーXのポート情報（メンバーID「X」はUnit IDで指定）
0x5000 | 1 ワード | HEX | R | ポート#1の動作状態
0x5001 | 1 ワード | HEX | R/W | ポート#1の設定状態
0x5002 | 1 ワード | HEX | R/W | ポート#1のPoE給電状態
0x5003 | 1 ワード | UINT | R | ポート#1の信号線（1,2,3,6）におけるPoE出力電力（mW）
0x5004 | 1 ワード | UINT | R | ポート#1の予備線（4,5,7,8）におけるPoE出力電力（mW）
0x5005 | 4 ワード | UINT | R | ポート#1の受信バイト数
0x5009 | 4 ワード | UINT | R | ポート#1の送信バイト数
0x500D | 1 ワード | HEX | R | ポート#2の動作状態
... これ以降、ポート#2～400までの情報が続く
0x6443 | 1 ワード | HEX | R | ポート#400の動作状態
0x6444 | 1 ワード | HEX | R/W | ポート#400の設定状態
0x6445 | 1 ワード | HEX | R/W | ポート#400のPoE給電状態
0x6446 | 1 ワード | UINT | R | ポート#400の信号線（1,2,3,6）におけるPoE出力電力（mW）
0x6447 | 1 ワード | UINT | R | ポート#400の予備線（4,5,7,8）におけるPoE出力電力（mW）
0x6448 | 4 ワード | UINT | R | ポート#400の受信バイト数
0x644C | 4 ワード | UINT | R | ポート#400の送信バイト数
未使用領域
0x6450 | - | - | - | これ以降は未使用

### マスターハートビート時間

マスターハートビート時間（HEX型）は、マスターハートビート（TCPハートビート）機能のタイムアウト時間を設定するためのレジスターです。
マスターハートビート機能では、クライアント（MODBUSマスター）から一定期間（タイムアウト時間）要求を受信しなかった場合にログメッセージを出力し、既定のレジスター内に満了フラグを立てます。
マスターハートビート機能とログメッセージトリガー（type logコマンド）を併用すれば、クライアントからの通信が途絶えた場合にポートをシャットダウンするなどの自動的な対応をとることができます。
Note

本レジスターおよびハートビートタイマーはシステム内に1つだけ存在します。クライアントごとに管理されるものではありません。

マスターハートビート時間（HEX型）の定義および用法は次のとおりです。

- 本レジスターのサイズは1ワード（16ビット）ですが、上位8ビットは未使用のため、値の有効範囲は0～255（秒）です。有効範囲外の値を書き込もうとした場合はエラーになります。
- 起動直後の初期値は0です。
- いずれかのクライアントが本レジスターに1～255（秒）の範囲の値を書き込むと、指定値をタイムアウト時間とするハートビートタイマーがスタートします。
  また、書き込みによってレジスターの値が変更された場合は次のようなnoticeレベルのログメッセージが出力されます（Xはタイムアウト時間）。

      MODBUS: Master heartbeat timer started for X seconds

- ハートビートタイマーの動作中にいずれかのクライアントが本レジスターの値を読み出した場合は、その時点での設定値が返ります。
- ハートビートタイマーの動作中にいずれかのクライアントからなんらかのMODBUS要求を受信すると、タイマーはリセットされて再スタートします。
- ハートビートタイマーのスタート後、どのクライアントからもMODBUS要求を受信しないままタイムアウト時間が経過すると、ハートビートタイマーは満了し、次のようなwarningレベルのログメッセージが出力されます（Xはタイムアウト時間）。

      MODBUS: Master heartbeat timer expired: X seconds with no requests

- ハートビートタイマーの満了後に本レジスターの値を読みだした場合は、0が返ります。
- ハートビートタイマーの満了後は、スレーブハートビートレジスターのビット16が1になります。
- いずれかのクライアントが本レジスターに0を書き込むと、動作中のハートビートタイマーはストップします。
  また、書き込みによってレジスターの値が変更された場合は次のnoticeレベルのログメッセージが出力されます。

      MODBUS: Master heartbeat timer halted

- いずれかのクライアントが本レジスターになんらかの値を書き込むと、スレーブハートビートレジスターのビット16はクリアされ0になります。
- ハートビートタイマーの状態（Not Set、Active、Expired）や設定はshow scada modbus tcp serverコマンドで確認できます。

### スレーブハートビート

スレーブハートビート（HEX型）の定義は次のとおりです。
Note

本レジスターはシステム内に1つだけ存在します。クライアントごとに管理されるものではありません。

- ここでは下位ビットからビット1,2,3...,16と呼ぶものとします。
- ビット1～8（下位バイト）はつねに動作し続ける単位100ミリ秒（0.1秒）のカウンターです。取りうる値の範囲は0～255（0～25.5秒）であり、255を超えると0に戻って循環します。
- ビット9～13は下記の間隔で1と0が切り替わるトグルビットです。
  - ビット9：500ミリ秒（0.5秒）
  - ビット10：1秒
  - ビット11：5秒
  - ビット12：10秒
  - ビット13：30秒
- ビット14と15は未使用のため値はつねに0です。
- ビット16はマスターハートビートがタイムアウトした場合に1、そうでない場合は0を示します。
- 本レジスターはシステム内に1つだけ存在するグローバルなレジスターです。クライアントごとのタイマーではありません。

### 製品（部品）種別

製品（部品）種別（ENUM型）の定義は次のとおりです。

1. 本体
2. 拡張モジュール
3. 電源ユニット
4. ファンモジュール
5. シャーシのバックプレーン
6. 拡張モジュールのサブボード

### センサー種別

センサー種別（ENUM型）の定義は次のとおりです。

1. 電圧
2. 温度
3. ファン回転数
4. 電流
5. 電力
6. 存在有無
7. 給電有無
8. 入力有無
9. 外部アラーム入力端子の状態
10. 外部アラーム出力端子の状態
11. FAULT LEDの点灯状態

### センサー単位

センサー単位（ENUM型）の定義は次のとおりです。

1. V（ボルト）
2. ℃（摂氏温度）
3. RPM（1分間あたり回転数）
4. A（アンペア）
5. W（ワット）

### アラーム種別

アラーム種別（ENUM型）の定義は次のとおりです。

1. 外部電源ユニット
2. EPSR
3. 外部アラーム入力端子
4. ポートのリンクダウン
5. ループ検出
6. PoE電源ユニット障害
7. PoEポート障害
8. 温度
9. G.8032
10. UFO

### アラーム設定

アラーム設定（HEX型）の定義は次のとおりです。

- 出力先メンバーID 1～4
  - ここでは上位ビットからビット1,2,3...,16と呼ぶものとします。各ビットの値は0が未設定、1が設定ありを表します。
  - ビット1：（スタックメンバー1）LEDの設定有無
  - ビット2：（スタックメンバー1）アラーム出力端子1の設定有無
  - ビット3：（スタックメンバー1）アラーム出力端子2の設定有無
  - ビット4：（スタックメンバー1）アラーム出力端子3の設定有無
  - ビット5：（スタックメンバー2）LEDの設定有無
  - ビット6：（スタックメンバー2）アラーム出力端子1の設定有無
  - ビット7：（スタックメンバー2）アラーム出力端子2の設定有無
  - ビット8：（スタックメンバー2）アラーム出力端子3の設定有無
  - ビット9：（スタックメンバー3）LEDの設定有無
  - ビット10：（スタックメンバー3）アラーム出力端子1の設定有無
  - ビット11：（スタックメンバー3）アラーム出力端子2の設定有無
  - ビット12：（スタックメンバー3）アラーム出力端子3の設定有無
  - ビット13：（スタックメンバー4）LEDの設定有無
  - ビット14：（スタックメンバー4）アラーム出力端子1の設定有無
  - ビット15：（スタックメンバー4）アラーム出力端子2の設定有無
  - ビット16：（スタックメンバー4）アラーム出力端子3の設定有無
- 出力先メンバーID 5～8
  - ここでは上位ビットからビット1,2,3...,16と呼ぶものとします。各ビットの値は0が未設定、1が設定ありを表します。
  - ビット1：（スタックメンバー5）LEDの設定有無
  - ビット2：（スタックメンバー5）アラーム出力端子1の設定有無
  - ビット3：（スタックメンバー5）アラーム出力端子2の設定有無
  - ビット4：（スタックメンバー5）アラーム出力端子3の設定有無
  - ビット5：（スタックメンバー6）LEDの設定有無
  - ビット6：（スタックメンバー6）アラーム出力端子1の設定有無
  - ビット7：（スタックメンバー6）アラーム出力端子2の設定有無
  - ビット8：（スタックメンバー6）アラーム出力端子3の設定有無
  - ビット9：（スタックメンバー7）LEDの設定有無
  - ビット10：（スタックメンバー7）アラーム出力端子1の設定有無
  - ビット11：（スタックメンバー7）アラーム出力端子2の設定有無
  - ビット12：（スタックメンバー7）アラーム出力端子3の設定有無
  - ビット13：（スタックメンバー8）LEDの設定有無
  - ビット14：（スタックメンバー8）アラーム出力端子1の設定有無
  - ビット15：（スタックメンバー8）アラーム出力端子2の設定有無
  - ビット16：（スタックメンバー8）アラーム出力端子3の設定有無

### ポート動作状態・設定状態

ポート動作状態と設定状態（HEX型）の定義は次のとおりです。

- ここでは1ワード（16ビット）を上位から4ビットずつ区切り、それぞれをニブル1,2,3,4と呼ぶものとします。
- 各ニブルは16進数の1桁に相当し、それぞれの値は次の意味を持ちます。

  ニブル1 | 管理状態
  0x0000 | DOWN
  0xF000 | UP
  ニブル2 | デュプレックスモード
  0x0000 | auto
  0x0100 | full
  0x0200 | half
  ニブル3 | 極性
  0x0000 | auto
  0x0010 | MDI
  0x0020 | MDI-X
  ニブル4 | 通信速度
  0x0000 | auto
  0x0001 | 10Mbps
  0x0002 | 100Mbps
  0x0003 | 1Gbps
  0x0004 | 10Gbps

- たとえば、あるポートにおいて動作状態の取得値が「0xF103」だった場合、次のように解釈します。
  - ニブル1（管理状態）は「F」なので「UP」
  - ニブル2（デュプレックスモード）は「1」なので「full」
  - ニブル3（極性）は「0」なので「auto」
  - ニブル4（通信速度）は「3」なので「1Gbps」
- 設定状態の取得値も同様です。たとえば、あるポートにおいて設定状態の取得値が「0xF000」だった場合、次のように解釈します。
  - ニブル1（管理状態）は「F」なので「UP」
  - ニブル2（デュプレックスモード）は「0」なので「auto」
  - ニブル3（極性）は「0」なので「auto」
  - ニブル4（通信速度）は「0」なので「auto」
- 設定状態を変更するときも同様にして変更後の値を組み立ててください。
  たとえば、前記ポートの管理状態をDOWNに変更したい場合は、ニブル1（管理状態）のみ「0」（DOWN）に変更した「0x0000」を該当ポートの設定状態レジスターに書き込んでください。
  Note

  設定・状態変更の対象はスイッチポートのみで、LAGインターフェース等は対象外です。

### ポートPoE給電状態

ポートPoE給電状態（HEX型）の定義は次のとおりです。

- ここでは1ワード（16ビット）を上位から1バイト（8ビット）ずつ区切り、それぞれをバイト1,2と呼ぶものとします。
- 各バイトは16進数の2桁に相当し、それぞれの値は次の意味を持ちます。

  バイト1 | 信号線（1,2,3,6）におけるPoE給電状態
  0x0000 | 無効
  0xFF00 | 有効
  バイト2 | 予備線（4,5,7,8）におけるPoE給電状態
  0x0000 | 無効
  0x00FF | 有効

  Note

  本製品のPoE給電機能は予備線を使用しないため、ポートPoE給電状態の読み出しではバイト2がつねに0となり、バイト2を変更する書き込みを行っても動作には影響を与えません。