webrelay-modbus/stabiliti.py

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