"""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)