Files
CIP-Devices/powerflex.py
2017-05-19 17:01:48 -05:00

191 lines
8.8 KiB
Python

"""Class definition of PowerFlex Drives."""
from cpppo.server.enip.get_attribute import proxy_simple
import traceback
from common import reverse_parameter_name, bitfield, CIP_value
class powerflex(proxy_simple):
"""Generic powerflex drive."""
pass
COMMAND_MAP = {"Logic Status": {
0: "Run Ready",
1: "Active",
2: "Command Direction",
3: "Actual Direction",
4: "Accelerating",
5: "Decelerating",
6: "Alarm",
7: "Fault",
8: "At Setpoint Speed",
9: "Manual",
16: "Running",
17: "Jogging",
18: "Stopping",
19: "DC Brake",
20: "DB Active",
21: "Speed Mode",
22: "Position Mode",
23: "Torque Mode",
24: "At Zero Speed",
25: "At Home",
26: "At Limit",
27: "Current Limit",
28: "Bus Freq Reg",
29: "Enable On",
30: "Motor Overload",
31: "Regen",
}, "Logic Command": {
0: "Normal Stop",
1: "Start",
2: "Jog 1",
3: "Clear Fault",
6: "Manual",
16: "Coast Stop",
17: "Current Limit Stop",
18: "Run",
19: "Jog 2",
}}
class powerflex755(powerflex):
"""Specific parameters and their addresses, for the PowerFlex 750 Series AC drives."""
RUNNING_PARAMETERS = dict(output_frequency=powerflex.parameter('@0x93/1/9', 'REAL', 'Hz'),
speed_ref=powerflex.parameter('@0x93/2/9', 'REAL', 'Hz'),
motor_velocity=powerflex.parameter('@0x93/3/9', 'REAL', 'Hz/RPM'),
output_current=powerflex.parameter('@0x93/7/9', 'REAL', 'Amps'),
output_voltage=powerflex.parameter('@0x93/8/9', 'REAL', 'VAC'),
output_power=powerflex.parameter('@0x93/9/9', 'REAL', 'kW'),
output_powerfactor=powerflex.parameter('@0x93/10/9', 'REAL', 'kW'),
dc_bus_volts=powerflex.parameter('@0x93/11/9', 'REAL', 'VDC'),
elapsed_mwh=powerflex.parameter('@0x93/13/9', 'REAL', 'MWh'),
elapsed_kwh=powerflex.parameter('@0x93/14/9', 'REAL', 'kWh'),
elapsed_run_time=powerflex.parameter('@0x93/15/9', 'REAL', 'Hrs'),
speed_ref_a_stpt=powerflex.parameter('@0x93/546/9', 'REAL', 'Hz'),
)
CONFIGURATION_PARAMETERS = dict(motor_namplate_volts=powerflex.parameter('@0x93/25/9', 'REAL', 'VAC'),
motor_namplate_amps=powerflex.parameter('@0x93/26/9', 'REAL', 'Amps'),
motor_namplate_hertz=powerflex.parameter('@0x93/27/9', 'REAL', 'Hertz'),
motor_namplate_rpm=powerflex.parameter('@0x93/28/9', 'REAL', 'RPM'),
motor_namplate_powerunits=powerflex.parameter('@0x93/29/9', 'DINT', 'HP/kW'),
motor_namplate_power=powerflex.parameter('@0x93/30/9', 'REAL', 'HP/kW'),
motor_poles=powerflex.parameter('@0x93/31/9', 'DINT', 'Poles'),
pwm_frequency=powerflex.parameter('@0x93/38/9', 'REAL', 'kHz'),
rated_volts=powerflex.parameter('@0x93/20/9', 'REAL', 'VAC'),
rated_amps=powerflex.parameter('@0x93/21/9', 'REAL', 'Amps'),
rated_kw=powerflex.parameter('@0x93/22/9', 'REAL', 'kW'),
speed_units=powerflex.parameter('@0x93/300/9', 'DINT', 'Hz/RPM'),
duty_rating=powerflex.parameter('@0x93/306/9', 'DINT', 'ND/HD/LD'),
reset_meters=powerflex.parameter('@0x93/336/9', 'DINT', 'Ready/Energy/Time'),
db_resistor_type=powerflex.parameter('@0x93/382/9', 'DINT', 'Internal/External'),
db_resistor_ohms=powerflex.parameter('@0x93/383/9', 'REAL', 'Ohms'),
db_resistor_watts=powerflex.parameter('@0x93/384/9', 'REAL', 'Watts'),
speed_ref_a_sel=powerflex.parameter('@0x93/545/9', 'DINT', 'Param'),
)
COMMAND_PARAMETERS = dict(logic_status=powerflex.parameter('@0x07/3/4', 'DINT', 'Bits'),
logic_command=powerflex.parameter('@0x07/4/1', 'BOOL', 'Bits'))
PARAMETERS = powerflex.PARAMETERS.copy()
PARAMETERS.update(RUNNING_PARAMETERS)
PARAMETERS.update(CONFIGURATION_PARAMETERS)
PARAMETERS.update(COMMAND_PARAMETERS)
# PARAMETERS = dict(powerflex.PARAMETERS + RUNNING_PARAMETERS + CONFIGURATION_PARAMETERS)
def __init__(self, hostname):
"""Intitialize the class."""
super().__init__(hostname, route_path=[], send_path='')
self.PARAMETER_NAMES = [reverse_parameter_name(p) for p in self.PARAMETERS]
self.PARAMETER_NAMES = self.PARAMETER_NAMES[3:]
self.RUNNING_PARAMETER_NAMES = [reverse_parameter_name(p) for p in self.RUNNING_PARAMETERS]
self.CONFIGURATION_PARAMETER_NAMES = [reverse_parameter_name(p) for p in self.CONFIGURATION_PARAMETERS]
self.COMMAND_PARAMETER_NAMES = [reverse_parameter_name(p) for p in self.COMMAND_PARAMETERS]
self.running_values = {}
self.configuration_values = {}
self.command_values = {}
for p in self.RUNNING_PARAMETERS:
self.running_values[reverse_parameter_name(p)] = CIP_value(reverse_parameter_name(p), self.RUNNING_PARAMETERS[p][2])
for p in self.CONFIGURATION_PARAMETERS:
self.configuration_values[reverse_parameter_name(p)] = CIP_value(reverse_parameter_name(p), self.CONFIGURATION_PARAMETERS[p][2])
for p in self.COMMAND_PARAMETERS:
self.command_values[reverse_parameter_name(p)] = CIP_value(reverse_parameter_name(p), self.COMMAND_PARAMETERS[p][2])
# print("Speed Ref A Set: {}".format(self.write_parameter("Speed Ref A Sel", 'DINT', 546))) # Set the Speed ref to read from Ethernet Adapter
def get_all_values(self):
"""Retrieve all values stored for the VFD."""
temp = self.configuration_values.copy()
temp.update(self.running_values)
return temp
def write_parameter(self, param_name, param_type, value):
"""Write a parameter to the VFD."""
param = '%s = (%s)%s' % (param_name, param_type, value)
print(param)
try:
via = self
with via: # establish gateway, detects Exception (closing gateway)
val, = via.write(
via.parameter_substitution(param), checking=True)
if val:
return True
else:
return False
except Exception as exc:
print("Exception writing Parameter %s: %s, %s", param, exc, traceback.format_exc())
return False
def read_all(self):
"""Read all values from the list of parameter names."""
self.read_running()
self.read_configuration()
self.read_command()
return self.get_all_values()
def read_running(self):
"""Read Running Parameter values from the list of parameter names."""
values = list(self.read(self.parameter_substitution(self.RUNNING_PARAMETER_NAMES)))
for x in range(0, len(values)):
if values[x] is not None:
self.running_values[self.RUNNING_PARAMETER_NAMES[x]].update(values[x][0])
return self.running_values
def read_configuration(self):
"""Read Running Parameter values from the list of parameter names."""
values = list(self.read(self.parameter_substitution(self.CONFIGURATION_PARAMETER_NAMES)))
for x in range(0, len(values)):
if values[x] is not None:
self.configuration_values[self.CONFIGURATION_PARAMETER_NAMES[x]].update(values[x][0])
return self.configuration_values
def read_command(self):
"""Read Command Parameter values from the list of parameter names."""
values = list(self.read(self.parameter_substitution(self.COMMAND_PARAMETER_NAMES)))
for x in range(0, len(values)):
if values[x] is not None:
bit_map = bitfield(values[x][0])
value_map = {}
for i in range(0, len(bit_map)):
try:
value_map[COMMAND_MAP[self.COMMAND_PARAMETER_NAMES[x]][i]] = bit_map[i]
except KeyError:
pass
self.command_values[self.COMMAND_PARAMETER_NAMES[x]].update(value_map)
return self.command_values
def start(self):
"""Start the VFD."""
return self.write_parameter("Logic Command", "INT", 2)
def stop(self):
"""Start the VFD."""
return self.write_parameter("Logic Command", "INT", 1)