132 lines
4 KiB
Python
132 lines
4 KiB
Python
import easymodbus.modbusClient
|
|
from datetime import datetime as dt
|
|
from functools import reduce
|
|
|
|
class StabilitiController(object):
|
|
''''''
|
|
def __init__(self, ipaddr, port=502, uid=240):
|
|
self.client = easymodbus.modbusClient.ModbusClient(ipaddr, port)
|
|
self.client.unitidentifier = uid
|
|
|
|
def checkConnect(self):
|
|
if not self.client.is_connected():
|
|
self.client.connect()
|
|
|
|
def checkClose(self):
|
|
if self.client.is_connected():
|
|
self.client.close()
|
|
|
|
def reg2str(self, r):
|
|
ms = (r & 0xff00) >> 8
|
|
ls = (r & 0xff)
|
|
return chr(ms) + chr(ls)
|
|
|
|
def getNetworkConfigs(self, config=None):
|
|
self.checkConnect()
|
|
configDict = {}
|
|
from functools import reduce
|
|
if config:
|
|
pass
|
|
else:
|
|
holdingRegisters = self.client.read_holdingregisters(2030,8)
|
|
configDict["ipaddr"] = (reduce (lambda a, b: str(a)+str(b), map(self.reg2str, holdingRegisters)))
|
|
holdingRegisters = self.client.read_holdingregisters(2038,8)
|
|
configDict["netmask"] = (reduce (lambda a, b: str(a)+str(b), map(self.reg2str, holdingRegisters)))
|
|
|
|
return configDict
|
|
|
|
def reg2utc(self, timel, timeu):
|
|
return dt.fromtimestamp((timeu << 16) + timel)
|
|
|
|
def reg2bits(self, reg):
|
|
return bin(reg)[2:].zfill(16)
|
|
|
|
def resetPcs(self):
|
|
self.checkConnect()
|
|
self.client.write_single_register(266, 0x8000)
|
|
|
|
def checkOpMode(self):
|
|
self.checkConnect()
|
|
val = self.client.read_holdingregisters(267, 1)
|
|
print (val)
|
|
return val[0] == 1
|
|
|
|
def readFaultDetail(self, findex):
|
|
if not (0<=findex<=63):
|
|
return None
|
|
|
|
self.checkConnect()
|
|
|
|
self.client.write_single_register(0, findex)
|
|
regs = self.client.read_holdingregisters(1, 9)
|
|
flimit, fval, fcount, ftimel, ftimeu = regs[:5]
|
|
fselector, fstatus = regs[-2:]
|
|
fselector = bin(fselector)[2:].zfill(16)[-3:]
|
|
print(bin(fstatus)[2:].zfill(16))
|
|
fseverity = bin(fstatus)[2:].zfill(16)[-3:]
|
|
'''
|
|
b0-b2: The severity of the fault.
|
|
0x000 = Info: increments the fault counter only.
|
|
0x001 = Alert: increments the fault counter only.
|
|
0x010 = Alarm: fault is logged.
|
|
0x011 = Abort 0: fault is logged and unit is stopped. Reconnect timer 0 is used for restart.
|
|
0x100 = Abort 1: fault is logged and unit is stopped. Reconnect timer 1 is used for restart.
|
|
0x101 = Abort 2: fault is logged and unit is stopped. Reconnect timer 2 is used for restart.
|
|
0x110 = Lockdown: fault is logged, unit stops processing power and requires a reset.
|
|
0x111 = Reserved
|
|
'''
|
|
fstatus = bin(fstatus)[2:].zfill(16)[-5:-3]
|
|
'''
|
|
b3-b4: The status of the fault.
|
|
0x01 = No fault
|
|
0x10 = Active
|
|
0x11 = Occurred
|
|
'''
|
|
print(flimit, fval, fcount,
|
|
self.reg2utc(ftimel, ftimeu),
|
|
fselector,
|
|
fstatus,
|
|
fseverity
|
|
)
|
|
|
|
return {
|
|
"Number": findex,
|
|
"Limit": flimit,
|
|
"Value": fval,
|
|
"Occurence": fcount,
|
|
"TimeStamp": self.reg2utc(ftimel, ftimeu),
|
|
"Selector": fselector,
|
|
"Severity": fseverity,
|
|
"Status": fstatus,
|
|
}
|
|
|
|
def readFaultArray(self, start):
|
|
|
|
import operator as op
|
|
self.checkConnect()
|
|
|
|
faults = self.client.read_holdingregisters(start,4)
|
|
faultStrings = map(lambda x: bin(x)[2:].zfill(16)[::-1], faults)
|
|
return reduce(op.add, faultStrings)
|
|
|
|
def readFaultActivity(self):
|
|
return self.readFaultArray(16)
|
|
|
|
def readFaultOccurence(self):
|
|
return self.readFaultArray(24)
|
|
|
|
def printAllFaults(self, faults):
|
|
fmt = " {} || {} | {} | {} | {} | {} | {} | {} | {} "
|
|
sep = " ================================== "
|
|
print (fmt.format(" ", *list(range(8))))
|
|
print (sep)
|
|
for i in range(8):
|
|
idx = i * 8
|
|
print (fmt.format(i, *faults[idx:idx+8]))
|
|
|
|
def reconnectTimer(self):
|
|
pass
|
|
|
|
def getSystemStatus(self):
|
|
pass
|
|
|