ems/Connector/modules/modbus.py

89 lines
2.2 KiB
Python

'''
Created on 05.12.2013
@author: Philipp Rauch
'''
from pymodbus.client.sync import ModbusTcpClient
from datetime import datetime
from profile.datasheet import Datasheet
import struct
def setup(conf):
PACS = []
csv = '%s/%s' % (conf['config_dictionary'], conf['pac_csvfile'])
pac_csv = Datasheet()
pac_csv.loadDatasheet(strFile = csv)
messages = pac_csv.readDatasheet()
### INITIALIZE ###
PACS.append(messages)
for ip in conf['pac_ip']:
PACS.append(ModbusTcpClient(ip))
### CONNECT ###
for PAC in PACS[1::]:
PAC.connect()
return PACS
def loop(PACS, item):
row = PACS[0][PACS[0]['offset'] == item]
inx = row.index.values[0]
#print row.get('value - type')[inx]
valType = row.get('value - type')[inx]
reg = row.get('size (Byte)')[inx]/2
type_picker = {'double' : _to_double,
'float' : _to_float,
'float + timestamp' : _to_float_time,
'long' : _to_long,
'timestamp' : _to_time_abs,
'Unsigned long' : _to_ulong,
'Unsigned short' : _to_ushort }
func = type_picker.get(valType, None)
if func is None:
raise NotImplementedError
res = PACS[2].read_holding_registers(item,reg,unit=1)
return { row.get('Value name')[inx] : func(res.registers) }
def _to_float_time(reg):
res = { 'value' : _to_float(reg[0:2]) }
res.update({ 'time' : _to_time_abs(reg[2:6]) })
return res
def _to_long(reg):
tmp = _to_ulong(reg)
s = struct.pack('=i', tmp)
return struct.unpack('=l', s)[0]
def _to_double(reg):
tmp = int(reg[0]) << 3*16 | int(reg[1]) << 2*16 | int(reg[2]) << 16 | int(reg[3])
s = struct.pack('=q', tmp)
return struct.unpack('=d', s)[0]
def _to_time_abs(reg):
timestamp = _to_ulong(reg)
date = datetime.fromtimestamp(timestamp)
return str(date)
def _to_ulong(reg):
return int(reg[0]) << 16 | int(reg[1])
def _to_ushort(reg):
return reg[0]
def _to_float(reg):
tmp = _to_ulong(reg)
s = struct.pack('=i', tmp)
return struct.unpack('=f', s)[0]
def close(PACS):
### CLOSE ###
for PAC in PACS[1::]:
PAC.close()