はじめに
EtherNet/IP機器をいじってみたかったので、ヤフオクでS8VK-X12024A-EIPを買って試してみた
使用機器
制御対象:S8VK-X12024A-EIP
制御元(PC):Ubuntu20.04 + python3.8.10
機器設定用PC:Windows11
S8VK-X12024A-EIPの設定
IPの固定やデフォルトゲートウェイの設定をするためにPower Supply Monitoring Toolというメーカー純正ソフトで設定をした(Windowsアプリケーション)
中古で買った機器だったため、何か設定が残っていてはじめ上手く接続できなかったけど、本体側のリセット(RSTボタンを押したまま電源を入れ、10秒待つ)を実施したら設定できた
pycomm3 とは
python3で使えるEtherNet/IP用のライブラリ
詳しくはドキュメントを読みましょう
インストールはpip install pycomm3で入る
機器情報の取得
ネットワーク上の機器をサーチするのは以下のコードで実行できる
この場合機器のIPを知っておく必要はなく、ブロードキャストで応答した機器が情報を返してくれるっぽい
import pycomm3
res = pycomm3.CIPDriver.discover()
print(res)
[{'encap_protocol_version': 1, 'ip_address': '192.168.xxx.xxx', 'vendor': 'Omron Corporation', 'product_type': 'UNKNOWN', 'product_code': 1680, 'revision': {'major': 1, 'minor': 2}, 'status': b'\x00\x00', 'serial': 'xxxxxx', 'product_name': 'S8VK-X12024A-EIP', 'state': 255}]
電圧・電流データの取得
S8VK-Xシリーズは電源ユニットなので、出力している電圧や電流等のデータをEtherNet/IP経由で取得できる
詳しい情報はメーカーHPから通信マニュアルを取得できる
import pycomm3
DEVICE_IP = '機器のIP'
with pycomm3.CIPDriver(DEVICE_IP) as driver:
driver.open()
res = driver.generic_message(
service=pycomm3.Services.get_attributes_all,
class_code=0x0372,
instance=0x01)
buffer = res[1]
print(buffer)
b'\x00\x01V\t\x00\x00\x08\x02\x87\x00\xd9\x03\x08\x07\x00\x00G\x00\x00\x00\xa7\x01'
実行するとこんな感じで各種データが取得できる
全データをまとめて取得するとByte配列になっているので見やすいように整形する
import struct
# 最初の12バイトを2バイトずつUINTとしてunpack
uint1 = struct.unpack_from('<H', buffer, 0)[0]
uint2 = struct.unpack_from('<H', buffer, 2)[0]
uint3 = struct.unpack_from('<H', buffer, 4)[0]
uint4 = struct.unpack_from('<H', buffer, 6)[0]
uint5 = struct.unpack_from('<H', buffer, 8)[0]
uint6 = struct.unpack_from('<H', buffer, 10)[0]
# 残りの8バイトをDWORD型としてunpack
dword1 = struct.unpack_from('<I', buffer, 12)[0]
dword2 = struct.unpack_from('<I', buffer, 16)[0]
data = {}
data['status_bits'] = bin(uint1)
data['voltage'] = uint2 / 100
data['current1'] = uint3 / 100
data['current2'] = uint4 / 100
data['lifetime1'] = uint5 / 10
data['lifetime2'] = uint6 / 10
data['total_operating_time'] = dword1
data['runtime'] = dword2
# 結果の表示
for key, value in data.items():
if key == 'voltage':
print(f" {key}: {value:.2f} V")
elif key == 'current1':
print(f" {key}: {value:.2f} A")
elif key == 'current2':
print(f" {key}: {value:.2f} A")
elif key == 'lifetime1':
print(f" {key}: {value:.1f} 年")
elif key == 'lifetime2':
print(f" {key}: {value:.1f} %")
elif key == 'total_operating_time':
print(f" {key}: {value} 時間")
elif key == 'runtime':
print(f" {key}: {value} 分")
else:
print(f" {key}: {value}")
status_bits: 0b100000000
voltage: 23.90 V
current1: 0.00 A
current2: 5.20 A
lifetime1: 13.5 年
lifetime2: 98.5 %
total_operating_time: 1800 時間
runtime: 71 分