メインコンテンツまでスキップ

M-Bus ドライバ

概要

M-Bus (Meter-Bus、EN 13757-2/3) の独自 Java native 実装。運用環境で一般的な wired M-Bus master ゲートウェイ、または シリアル-TCP コンバータ (Moxa NPort、USR-TCP232 など) に TCP socket で接続し、標準 M-Bus フレームを送受信します。

項目
opc_typeMBUS
実装クラスplantpulse.driver.protocol.mbus.MBusDriver
ライブラリ(なし — 独自実装。EN 13757-2/3)
read良好 (REQ_UD2 → RSP_UD)
write良好 (Slave Selection / Application Reset)
デフォルトポート10001 (Moxa NPort デフォルト)
セキュリティなし

クラス / 構造

MBusDriver (BaseProtocolDriver)
├── Socket / DataInputStream / OutputStream
├── defaultAddress — primary 1~250 (옵션)
├── synchronized requestUd2 / sendSlaveSelection / sendAppReset
├── MBusFrame — buildSndNke / buildReqUd2 / buildSlaveSelection
│ buildSndUdAppReset / parseLongFrame / parseAck
│ ACK=0xE5, START_LONG=0x68, SECONDARY_ADDRESS=253
├── MBusChecksum — sum(c+a+ci+data) mod 256
├── MBusBcd — encodeIdToBcd4(long), BCD 디코드
└── MBusDataRecord — DIF/VIF 파싱, parseAll(buf, off, len) → List<Record>
(Record { value, multiplier, unit, ... })

connect() :

  1. TCP 接続 (host:10001)。
  2. SND_NKE (Short Frame, C=0x40, A=default-address) を送信。
  3. ACK (0xE5) 受信の検証 — 応答がなくても connected=true (ゲートウェイにより差異あり)。

wire フォーマット概要

Short Frame (SND_NKE / Slave Selection 応答 ACK)

0x10 | C(1) | A(1) | CS(1) | 0x16
ACK 단독 = 0xE5

Long Frame (REQ_UD2 / RSP_UD)

0x68 | L | L | 0x68 | C(1) | A(1) | CI(1) | data... | CS(1) | 0x16
L = C + A + CI + data 의 byte 수
CS = (C+A+CI+data) mod 256
コマンドCCI意味
SND_NKE0x40Initialize slave
REQ_UD20x5BUser data 要求
Slave Selection0x530x52Secondary addressing
App Reset0x530x50Application reset

OPC 登録オプション (options)

キー意味デフォルト
default-addressprimary address (1~250)1
connect-timeoutms3000
read-timeoutms3000

タグアドレス形式

Primary addressing

表記意味
1:0primary 1、1 番目の record
5:2primary 5、3 番目の record
1primary 1、user-data 全体の hex

Secondary addressing

表記意味
secondary:12345678AB1C010716 hex 文字 (ID 4 + Mfg 2 + Ver 1 + Med 1)
secondary:<16-hex>:<recordIndex>上記 + record インデックス
select:12345678:43932:1:7十進エイリアス (id, mfg, ver, med)
select:12345678:43932:1:7:0+ record インデックス

trySecondaryAddress() は secondary slave selection を先に送信 → primary=253 で REQ_UD2。 ID は EN 13757-3 wire format の LSB-first BCD でエンコードされます (MBusBcd.encodeIdToBcd4)。

write アドレス形式

表記動作
secondary:<hex> / select:<id>:<mfg>:<ver>:<med>Slave selection のみ送信
app-reset:<subcode>primary=default-address に application reset
app-reset:<primary>:<subcode>primary を明示
select-and-reset:<id>:<mfg>:<ver>:<med>:<subcode>secondary 選択後に reset

subcode は address.value でも受け付けます。


record デコード

MBusDataRecord.parseAll(userData, off=12, len) が user-data (header 12 byte 以降) を DIF/VIF ベースで 巡回し、Record { value, multiplier, unit, ... } リストを返します。

formatValue(record) :

  • 整数 + multiplier=1 → Long.toString(...)
  • Number → value * multiplier (double)
  • その他 → String.valueOf(value)

対応 / 非対応

  • ✅ SND_NKE → REQ_UD2 → RSP_UD サイクル
  • ✅ Primary addressing (1~250)
  • ✅ Secondary addressing (slave selection + primary 253 read)
  • ✅ Application Reset (CI=0x50)
  • ✅ DIF/VIF data record パース + multiplier スケール
  • ❌ FCB (frame count bit) toggle / Multi-frame UD2
  • ❌ Wireless M-Bus (EN 13757-4)
  • ❌ Encryption (mode 5 / 7 — スマートメータ)

テストカバレッジ

test/java/plantpulse/driver/protocol/mbus/

クラステスト数
MBusAckTest4
MBusBcdTest13
MBusChecksumTest4
MBusDataRecordTest7
MBusDriverAddressTest10
MBusDriverWriteTest9
MBusFrameTest14
MBusSpecExtraTest28

計 89 テスト。


参考

  • EN 13757-2 Physical and link layer
  • EN 13757-3 Application layer / DIF/VIF / Secondary addressing
  • コード: src/plantpulse/driver/protocol/mbus/