def __init__(self): self.valves_status = { "Bay_2L-Busbar_2R": 0.0, "Bay_2L-Busbar_1R": 0.0, "Bay_2H-Busbar_B": 0.0, "Bay_2H-Busbar_2F": 0.0, "Bay_2H-Busbar_1F": 0.0, "Bay_2L-Busbar_B": 0.0, "Bay_3L-Busbar_2R": 0.0, "Bay_3L-Busbar_1R": 0.0, "Bay_3H-Busbar_B": 0.0, "Bay_3H-Busbar_2F": 0.0, "Bay_3H-Busbar_1F": 0.0, "Bay_3L-Busbar_B": 0.0, "Bay_4L-Busbar_2R": 0.0, "Bay_4L-Busbar_1R": 0.0, "Bay_4H-Busbar_B": 0.0, "Bay_4H-Busbar_2F": 0.0, "Bay_4H-Busbar_1F": 0.0, "Bay_4L-Busbar_B": 0.0, "Bay_5L-Busbar_1R": 0.0, "Bay_5L-Busbar_2R": 0.0, "Bay_5H-Busbar_B": 0.0, "Bay_5H-Busbar_1F": 0.0, "Bay_5H-Busbar_2F": 0.0, "Bay_5L-Busbar_B": 0.0, "Bay_6L-Busbar_1R": 0.0, "Bay_6L-Busbar_2R": 0.0, "Bay_6H-Busbar_B": 0.0, "Bay_6H-Busbar_1F": 0.0, "Bay_6H-Busbar_2F": 0.0, "Bay_6L-Busbar_B": 0.0, "Bay_7H-Busbar_1F": 0.0, "Bay_7H-Busbar_2F": 0.0, "Bay_7L-Busbar_1R": 0.0, "Bay_7L-Busbar_2R": 0.0, "Bay_8H-Busbar_1F": 0.0, "Bay_8H-Busbar_2F": 0.0, "Bay_8L-Busbar_1R": 0.0, "Bay_8L-Busbar_2R": 0.0 } self.pumps_status = { "Pump_Bay4": 0.0, "Pump_Bay5": 0.0, "Pump_Bay6": 0.0, "Pump_Bay7": 0.0, "Pump_Bay8": 0.0 } self.interface = syslab.HeatSwitchBoard(_BUILDING_NAME)
def PID_controller(self, inputs, process_ID, queue): print("Controller Constant Flow Started") interface = syslab.HeatSwitchBoard(_BUILDING_NAME) plt.show() plt.ion() self.xdata = [[], []] self.ydata = [[], []] f, (self.ax1, self.ax2) = plt.subplots(2, 1) self.ax1.set_xlim(0, 100) self.ax1.set_ylim(-50, +50) self.ax2.set_xlim(0, 100) self.ax2.set_ylim(-50, +50) self.line, = self.ax1.plot(self.xdata[0], self.ydata[0], 'r-') self.line2, = self.ax2.plot(self.xdata[1] * 2, self.ydata[1], 'b-') self.line.set_xdata(self.xdata) self.line.set_ydata(self.ydata) self.plot_array = [self.ax1, self.ax2] self.line_array = [self.line, self.line2] self.thresholds = [] start_time = time.time() self.n = 0 self.work_q = queue stopper = False active_circuit = True print("Control Process {0} started".format(process_ID)) print("I am process", process_ID) inputs = pickle.loads(inputs) print(inputs) self.process_ID = process_ID max = 100 min = 0 pumps_of_circuit = inputs["pumps_of_circuit"] kp = float(inputs["kp"]) kd = float(inputs["kd"]) ki = float(inputs["ki"]) gain = float(inputs["gain"]) circulators = inputs["circulator"] circulator_mode = int(inputs["circulator_mode"]) print(circulator_mode) feedback_sensor = inputs["feedback_sensor"] actuators = inputs["actuator"] valves = inputs["valves"] setpoint = [float(n) for n in inputs["setpoint"]] feedback_value = [_FIRST_OF_CLASS] * len(feedback_sensor) time_response = [_FIRST_OF_CLASS] * len(feedback_sensor) derivative = [_FIRST_OF_CLASS] * len(feedback_sensor) integral = [_FIRST_OF_CLASS] * len(feedback_sensor) windup_corrector = [_FIRST_OF_CLASS] * len(feedback_sensor) controller_output = [_FIRST_OF_CLASS] * len(actuators) controller_output_percentage = [_FIRST_OF_CLASS] * len(actuators) pre_error = [_FIRST_OF_CLASS] * len(feedback_sensor) actuator_signal = [_FIRST_OF_CLASS] * len(actuators) error_value = [_FIRST_OF_CLASS] * len(feedback_sensor) self.thresholds = [_FIRST_OF_CLASS] * len(feedback_sensor) CompositMess = [_FIRST_OF_CLASS] * len(actuators) for n in range(0, len(feedback_sensor)): title = "Time Response Signal Sensor " + feedback_sensor[n] self.plot_array[n].set_title(title) if len(feedback_sensor) < len(self.plot_array): title = "No more sensors" self.plot_array[-1].set_title(title) shut_down_signal = 0 shut_mess = CM(shut_down_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode = PM(circulator_mode, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in pumps_of_circuit: if pump not in circulators: print(circulator_mode) interface.setPumpControlMode(pump, mode) interface.stopPump(pump) time.sleep(0.2) print("Pump ", pump, "has been stopped") full_power_signal = 100 full_power = CM(full_power_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) print(circulators) for pump in circulators: interface.startPump(pump) interface.setPumpControlMode(pump, mode) interface.setPumpSetpoint(pump, full_power) time.sleep(0.2) print("Pump ", pump, "was started") start_time = time.time() counter_time = time.time() signal.signal(signal.SIGTERM, self.signal_term_handler) while (1): try: stop_time = time.time() if (not self.work_q.empty()): received_setpoint = self.work_q.get() setpoint = [float(n) for n in received_setpoint] self.n = 0 self.threshold = [_FIRST_OF_CLASS] * len(feedback_sensor) print("Control Thread {0} running".format(process_ID)) for n in range(_FIRST_OF_CLASS, len(feedback_sensor)): print(n) #feedback_value[n] = 1 feedback_value[n] = interface.getThermalPower( feedback_sensor[n]).value if not isinstance(feedback_value[n], float): feedback_value[n] = 0 # --->>> really bad though print( "feedback taken from sensor {0} with setpoint {1} is kW {2}" .format(feedback_sensor[n], setpoint[n], feedback_value[n])) print("The integral is {0} and the actuator signal is {1}". format(integral[n], actuator_signal[n])) print("Setpoint {0} was sent to actuator {1}".format( actuator_signal[n], actuators[n])) #print("The integral error is ", integral[n]) #print("The actuator signal is ", actuator_signal[n]) #print("Setpoint {0} was sent to actuator {1}".format(actuator_signal[n], actuators[n])) self.ydata[n].append( feedback_value[n]) # Save as previous error. self.xdata[n].append(time.time() - start_time) #feedback_value[n] = 0 self.update_line() if stop_time - counter_time > _CONTROL_TIME: print("I am actuating") for n in range(_FIRST_OF_CLASS, len(feedback_sensor)): error_value[n] = setpoint[n] - feedback_value[ n] # Calculate the error integral[n] = integral[n] + ki * error_value[ n] # - windup_corrector[n] # Calculate integral integral[n] = self.anti_windup(integral[n]) print("The integral error is ", integral[n]) actuator_signal[n] = integral[n] actuator_signal[n] = self.saturation( actuator_signal[n]) print("The actuator signal is ", actuator_signal[n]) CompositMess[n] = CM(actuator_signal[n], time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) interface.setMaxFlowLimit(actuators[n], CompositMess[n]) counter_time = time.time() time.sleep(_ACQUISITION_TIME) except (KeyboardInterrupt, SystemExit): for circulator in circulators: interface.stopPump(pump) print("Circulator {0} is now at zero flow".format( circulator)) sys.exit(0) except Exception: '''there is the condition because it will keep except''' self.shut_down_routine(pumps_of_circuit, valves, interface)
def PID_controller(self, inputs, process_ID, queue): inputs = pickle.loads(inputs) print(inputs) inputs = { 'controller_name': "['Source_1BH4']['Sink_1DL3']N", 'description': 'creator', 'gain': '1', 'kp': '5', 'ki': '8', 'kd': '0', 'ki_valve': '0.1', 'pumps_of_circuit': ['Pump_Bay4', 'Pump_Bay3'], 'circulator': ['Pump_Bay4'], 'circulator_mode': '0', 'actuator': ['Pump_Bay4'], 'setpoint': [4], 'feedback_sensor': ['Bay_3'], 'valves': [ 'Bay_4L-Busbar_2R', 'Bay_4H-Busbar_1F', 'Bay_3H-Busbar_2F', 'Bay_3L-Busbar_1R' ] } print("Controller Constant Flow Started") interface = syslab.HeatSwitchBoard(_BUILDING_NAME) plt.show() plt.ion() self.xdata = [[], []] self.ydata = [[], []] f, (self.ax1, self.ax2) = plt.subplots(2, 1) self.ax1.set_xlim(0, 100) self.ax1.set_ylim(-50, +50) self.ax2.set_xlim(0, 100) self.ax2.set_ylim(-50, +50) self.line, = self.ax1.plot(self.xdata[0], self.ydata[0], 'r-') self.line2, = self.ax2.plot(self.xdata[1] * 2, self.ydata[1], 'b-') self.line.set_xdata(self.xdata) self.line.set_ydata(self.ydata) self.plot_array = [self.ax1, self.ax2] self.line_array = [self.line, self.line2] self.thresholds = [] start_time = time.time() self.n = 0 self.work_q = queue first_call = True stopper = False active_circuit = True print("Control Process {0} started".format(process_ID)) print("I am process", process_ID) self.process_ID = process_ID max = 100 min = 0 valve_reg = False pumps_of_circuit = inputs["pumps_of_circuit"] kp = float(inputs["kp"]) kd = float(inputs["kd"]) ki = float(inputs["ki"]) ki_valve = float(inputs["ki_valve"]) gain = float(inputs["gain"]) circulators = inputs["circulator"] circulator_mode = int(inputs["circulator_mode"]) print(circulator_mode) feedback_sensor = inputs["feedback_sensor"] actuators = inputs["actuator"] valves = inputs["valves"] setpoint = [float(n) for n in inputs["setpoint"]] feedback_value = [_BEGIN_WITH] * len(feedback_sensor) time_response = [_BEGIN_WITH] * len(feedback_sensor) derivative = [_BEGIN_WITH] * len(feedback_sensor) integral = [_BEGIN_WITH] * len(feedback_sensor) integral[_BEGIN_WITH] = _MIN_SAT_PUMP integral_valve = [_BEGIN_WITH] * len(feedback_sensor) windup_corrector = [_BEGIN_WITH] * len(feedback_sensor) controller_output = [_BEGIN_WITH] * len(actuators) controller_output_percentage = [_BEGIN_WITH] * len(actuators) pre_error = [_BEGIN_WITH] * len(feedback_sensor) actuator_signal = [_BEGIN_WITH] * len(actuators) actuator_signal_valve = [_BEGIN_WITH] * len(actuators) error_value = [_BEGIN_WITH] * len(feedback_sensor) self.thresholds = [_BEGIN_WITH] * len(feedback_sensor) CompositMess = [_BEGIN_WITH] * len(actuators) for n in range(0, len(feedback_sensor)): title = "Time Response Signal Sensor " + feedback_sensor[n] self.plot_array[n].set_title(title) if len(feedback_sensor) < len(self.plot_array): title = "No more sensors" self.plot_array[-1].set_title(title) shut_down_signal = 0 shut_mess = CM(shut_down_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode = PM(circulator_mode, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in pumps_of_circuit: if pump not in circulators: print(circulator_mode) interface.setPumpControlMode(pump, mode) interface.stopPump(pump) time.sleep(0.2) print("Pump ", pump, "has been stopped") half_power_signal = 50 half_power = CM(half_power_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) print(circulators) n = 0 for pump in circulators: interface.startPump(pump) interface.setPumpControlMode(pump, mode) interface.setPumpSetpoint(pump, half_power) time.sleep(0.2) print("Pump ", pump, "was started") n += 1 start_time = time.time() counter_time = time.time() counter_time_valve = time.time() signal.signal(signal.SIGTERM, self.signal_term_handler) while (1): #try: stop_time = time.time() if (not self.work_q.empty()): received_setpoint = self.work_q.get() setpoint = [float(n) for n in received_setpoint] self.n = 0 self.threshold = [_BEGIN_WITH] * len(feedback_sensor) print("Control Thread {0} running".format(process_ID)) for n in range(_BEGIN_WITH, len(feedback_sensor)): print(n) #feedback_value[n] = 1 feedback_value[n] = interface.getThermalPower( feedback_sensor[n]).value if not isinstance(feedback_value[n], float): feedback_value[n] = 0 # --->>> really bad though print( "feedback taken from sensor {0} with setpoint {1} is kW {2}" .format(feedback_sensor[n], setpoint[n], feedback_value[n])) print("The error is {0}".format(error_value[n])) print( "The integral for pump is {0} and the actuator signal for pump is {1}" .format(integral[n], actuator_signal[n])) print("The actuator signal for valve is ", actuator_signal_valve[n]) print("Setpoint {0} was sent to actuator {1}".format( actuator_signal[n], actuators[n])) #print("The integral error is ", integral[n]) #print("The actuator signal is ", actuator_signal[n]) #print("Setpoint {0} was sent to actuator {1}".format(actuator_signal[n], actuators[n])) self.ydata[n].append( feedback_value[n]) # Save as previous error. self.xdata[n].append(time.time() - start_time) #feedback_value[n] = 0 self.update_line() if stop_time - counter_time > _CONTROL_TIME: if not valve_reg: print("I am actuating with pump") for n in range(_BEGIN_WITH, len(feedback_sensor)): error_value[n] = setpoint[n] - feedback_value[ n] # Calculate the error integral[n] = integral[n] + ki * error_value[ n] # - windup_corrector[n] # Calculate integral integral[n] = self.anti_windup(integral[n], "pump") print("The integral error is ", integral[n]) actuator_signal[n] = kp * error_value[n] + integral[n] actuator_signal[n] = self.saturation( actuator_signal[n], "pump") print("The actuator signal for pump is ", actuator_signal[n]) #actuator_signal[n] = self.pump_setpoint_converter(actuator_signal[n]) CompositMess[n] = CM(actuator_signal[n], time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) interface.setPumpSetpoint(actuators[n], CompositMess[n]) counter_time = time.time() '''if (abs(error_value[n]) > _TOLERANCE) and (actuator_signal[n] <= _MIN_SAT_PUMP) and not valve_reg: if first_call: print("30s start from here") start_time = time.time() first_call = False if (time.time() - start_time) >= 30: print("I am heeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer") integral_valve[0] = interface.getValvePosition("Bay_3L-Busbar_1R").value valve_reg = True else: counter_time = time.time() first_call = True''' ''' if valve_reg: print("I am actuating with valve") for n in range(_BEGIN_WITH, len(feedback_sensor)): error_value[n] = setpoint[n] - feedback_value[n] # Calculate the error integral_valve[n] = integral_valve[n] + ki_valve * error_value[n] # - windup_corrector[n] # Calculate integral integral_valve[n] = self.anti_windup(integral_valve[n], "valve") print("The valve integral error is ", integral_valve[n]) actuator_signal_valve[n] = integral_valve[n] actuator_signal_valve[n] = self.saturation(actuator_signal_valve[n], "valve") print("The actuator signal for valve is ", actuator_signal_valve[n]) CompositMess_Valve = CM(actuator_signal_valve[n], time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) interface.setValvePosition("Bay_3L-Busbar_1R", CompositMess_Valve) valve_position = interface.getValvePosition("Bay_3L-Busbar_1R").value #counter_time = time.time() if ((error_value[n] > _TOLERANCE) and (actuator_signal[n] <= _MIN_SAT_PUMP) and (valve_position >= 0.9)): valve_reg = False first_call = True integral[_BEGIN_WITH] = _MIN_SAT_PUMP else: counter_time = time.time()''' time.sleep(_ACQUISITION_TIME)
def PID_controller(self, inputs, process_ID, queue): inputs = pickle.loads(inputs) print(inputs) inputs = { 'controller_name': "['Source_1BH4']['Sink_1DL3']['Sink_1DL2']N", 'description': 'creator', 'gain': '1', 'kp': '0', 'ki': '0.1', 'kd': '0', 'ki_valve': '0.1', 'pumps_of_circuit': ['Pump_Bay4', 'Pump_Bay3'], 'circulator': ['Pump_Bay4'], 'circulator_mode': '4', 'actuator': ['Bay_2L-Busbar_1R', 'Bay_3L-Busbar_1R'], 'setpoint': [2, 4], 'feedback_sensor': ['Bay_2', 'Bay_3'], 'valves': [ 'Bay_4L-Busbar_2R', 'Bay_4H-Busbar_1F', 'Bay_3H-Busbar_2F', 'Bay_3L-Busbar_1R' ], 'sources_meters': ['Bay_4'] } print("Controller Constant Pressure Started") interface = syslab.HeatSwitchBoard(_BUILDING_NAME) plt.show() plt.ion() self.xdata = [[], []] self.ydata = [[], []] f, (self.ax1, self.ax2) = plt.subplots(2, 1) self.ax1.set_xlim(0, 100) self.ax1.set_ylim(-50, +50) self.ax2.set_xlim(0, 100) self.ax2.set_ylim(-50, +50) self.line, = self.ax1.plot(self.xdata[0], self.ydata[0], 'r-') self.line2, = self.ax2.plot(self.xdata[1] * 2, self.ydata[1], 'b-') self.line.set_xdata(self.xdata) self.line.set_ydata(self.ydata) self.plot_array = [self.ax1, self.ax2] self.line_array = [self.line, self.line2] self.thresholds = [] start_time = time.time() self.n = 0 self.work_q = queue first_call = True print("Control Process {0} started".format(process_ID)) print("I am process", process_ID) #inputs = pickle.loads(inputs) print(inputs) self.process_ID = process_ID max = 100 min = 0 pumps_of_circuit = inputs["pumps_of_circuit"] kp = float(inputs["kp"]) kd = float(inputs["kd"]) ki = float(inputs["ki"]) gain = float(inputs["gain"]) circulators = inputs["circulator"] circulator_mode = int(inputs["circulator_mode"]) print(circulator_mode) feedback_sensor = inputs["feedback_sensor"] actuators = inputs["actuator"] sources_meters = inputs['sources_meters'] valves = inputs["valves"] setpoint = [float(n) for n in inputs["setpoint"]] feedback_value = [float(_BEGIN_WITH)] * len(feedback_sensor) time_response = [_BEGIN_WITH] * len(feedback_sensor) derivative = [_BEGIN_WITH] * len(feedback_sensor) integral = [float(_BEGIN_WITH)] * len(feedback_sensor) half = 0.5 half = CM(half, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for actuator in actuators: interface.setValvePosition(actuator, half) for n in range(0, len(integral)): integral[n] = 0.5 # interface.getValvePosition(actuators[n]).value windup_corrector = [_BEGIN_WITH] * len(feedback_sensor) controller_output = [float(_BEGIN_WITH)] * len(actuators) controller_output_percentage = [_BEGIN_WITH] * len(actuators) pre_error = [_BEGIN_WITH] * len(feedback_sensor) actuator_signal = [float(_BEGIN_WITH)] * len(actuators) error_value = [float(_BEGIN_WITH)] * len(feedback_sensor) self.thresholds = [_BEGIN_WITH] * len(feedback_sensor) CompositMess = [_BEGIN_WITH] * len(actuators) historical_position = [_BEGIN_WITH] * len(actuators) ''' n = 0 for actuator in actuators: controller_output[n] = interface.getValvePosition(actuator).value n += 1''' for n in range(0, len(feedback_sensor)): title = "Time Response Signal Sensor " + feedback_sensor[n] self.plot_array[n].set_title(title) if len(feedback_sensor) < len(self.plot_array): title = "No more sensors" self.plot_array[-1].set_title(title) shut_down_signal = 0 shut_mess = CM(shut_down_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode = PM(circulator_mode, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in pumps_of_circuit: if pump not in circulators: print(circulator_mode) interface.stopPump(pump) time.sleep(0.2) print("Pump ", pump, "has been stopped") full_power_signal = 100 flow_limit_signal = 9 full_power = CM(full_power_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) flow_limit = CM(flow_limit_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) #optimum_pressure = self.find_optimum_pressure(circulators, interface, sources_meters) optimum_pressure = 100 optimum_pressure = CM(optimum_pressure, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in circulators: interface.startPump(pump) interface.setPumpControlMode(pump, mode) interface.setPumpSetpoint(pump, optimum_pressure) #interface.setMaxFlowLimit(pump, flow_limit) time.sleep(0.2) print("Pump ", pumps_of_circuit[n], "was started") time.sleep(12.5) start_time = time.time() integral_start = time.time() proportional_start = time.time() signal.signal(signal.SIGTERM, self.signal_term_handler) counter = 0 counter_min = 0 check_valves = True while (1): #try: stop_time = time.time() if (not self.work_q.empty()): received_setpoint = self.work_q.get() setpoint = [float(n) for n in received_setpoint] self.n = 0 self.threshold = [_BEGIN_WITH] * len(feedback_sensor) print("Control Thread {0} running".format(process_ID)) for n in range(_BEGIN_WITH, len(feedback_sensor)): print(n) #feedback_value[n] = 1 feedback_value[n] = float( interface.getThermalPower(feedback_sensor[n]).value) #print(float(interface.getThermalPower(feedback_sensor[n]).value)) if not isinstance(feedback_value[n], float): feedback_value[n] = 0 # --->>> really bad though print("It was nan") print("The Pumps are running at setpoint ", optimum_pressure.value) print( "feedback taken from sensor {0} with setpoint {1} is kW {2}" .format(feedback_sensor[n], setpoint[n], feedback_value[n])) print("The actuator signal is {0}".format(actuator_signal[n])) print("Setpoint {0} was sent to actuator {1}".format( actuator_signal[n], actuators[n])) print("The control output for ", actuators[n], " is ", controller_output[n]) print("The integral for ", actuators[n], " is ", integral[n]) self.ydata[n].append( feedback_value[n]) # Save as previous error. self.xdata[n].append(time.time() - start_time) #feedback_value[n] = 0 print(feedback_value[n]) historical_position[n] = interface.getValvePosition( actuators[n]).value self.update_line() if stop_time - proportional_start > _PROPORTIONAL_TIME: for n in range(_BEGIN_WITH, len(feedback_sensor)): error_value[n] = setpoint[n] - feedback_value[ n] # Calculate the error #print("The integral error is ", integral[n]) #controller_output[n] = kp * error_value[n] + ki * integral[n] '''this below is the real PID action as the controller action is really related to the errorr''' print("The Pumps are running at setpoint ", optimum_pressure) print("this is the error ", error_value[n]) integral[n] = integral[n] + ki * error_value[ n] # - windup_corrector[n] # Calculate integral integral[n] = self.anti_windup(integral[n]) print("The integral for ", actuators[n], " is ", integral[n]) #controller_output[n] = self.saturation(controller_output[n] + kp * error_value[n] + integral[n]) controller_output[n] = kp * error_value[n] + integral[n] print("The proportional action is ", kp * error_value[n]) print("The integral action is ", integral[n]) print("this is the controller output ", controller_output[n]) controller_output = self.apply_corrector_factor( historical_position, controller_output, ki) integral = controller_output #time.sleep(2) for n in range(_BEGIN_WITH, len(feedback_sensor)): actuator_signal[n] = self.saturation(controller_output[n]) print( "The actuator signal is corrected with corrector is ", actuator_signal[n]) CompositMess[n] = CM(actuator_signal[n], time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) interface.setValvePosition(actuators[n], CompositMess[n]) proportional_start = time.time() #if (sum(controller_output) > _MAX_SUM): if check_valves: for output in integral: if output >= _MAX_SAT: counter += 1 elif output <= _MIN_SAT: counter_min += 1 print("counter ", counter) print("counter_min ", counter_min) if (counter >= 1 or counter_min >= 1): check_valves = False if first_call: print("60s start from here") start_time = time.time() first_call = False if (time.time() - start_time) >= 50: print("I am adjusting pump setpoint") for pump in circulators: optimum_pressure = optimum_pressure.value + counter * _PUMP_VARIATION - counter_min * _PUMP_VARIATION if optimum_pressure > 100: optimum_pressure = 100 elif optimum_pressure < 10: optimum_pressure = 10 optimum_pressure = CM(optimum_pressure, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) print("Pump {0} was reduced to {1}".format( pump, optimum_pressure)) interface.setPumpSetpoint(pump, optimum_pressure) start_time = time.time() counter = 0 counter_min = 0 check_valves = True else: first_call = True #if stop_time - integral_start > _INTEGRAL_TIME: # for n in range(_BEGIN_WITH, len(feedback_sensor)): # error_value[n] = setpoint[n] - feedback_value[n] # Calculate the error # integral[n] = integral[n] + ki * error_value[n] # - windup_corrector[n] # Calculate integral # integral[n] = self.anti_windup(integral[n]) # controller_output[n] = controller_output[n] + integral[n] # print("The integral action is ", integral[n]) # print("this is the controller output ", controller_output[n]) # '''this below is the real PID action as the controller action is really related to the errorr''' # actuator_signal[n] = controller_output[n] # actuator_signal[n] = self.saturation(actuator_signal[n]) # print("The actuator signal is ", actuator_signal[n]) # CompositMess[n] = CM(actuator_signal[n], time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) # interface.setValvePosition(actuators[n], CompositMess[n]) # integral_start = time.time()''' time.sleep(_ACQUISITION_TIME)
"Bay_3L-Busbar_1R", "Bay_3L-Busbar_2R", "Bay_3L-Busbar_B", "Bay_4L-Busbar_2R", "Bay_4L-Busbar_1R", "Bay_4H-Busbar_B", "Bay_4H-Busbar_2F", "Bay_4H-Busbar_1F", "Bay_4L-Busbar_B", "Bay_5L-Busbar_1R", "Bay_5L-Busbar_2R", "Bay_5H-Busbar_B", "Bay_5H-Busbar_1F", "Bay_5H-Busbar_2F", "Bay_5L-Busbar_B", "Bay_6L-Busbar_1R", "Bay_6L-Busbar_2R", "Bay_6H-Busbar_B", "Bay_6H-Busbar_1F", "Bay_6H-Busbar_2F", "Bay_6L-Busbar_B", "Bay_7H-Busbar_1F", "Bay_7H-Busbar_2F", "Bay_7L-Busbar_1R", "Bay_7L-Busbar_2R", "Bay_8H-Busbar_1F", "Bay_8H-Busbar_2F", "Bay_8L-Busbar_1R", "Bay_8L-Busbar_2R" ] pumps = [ "Pump_Bay2", "Pump_Bay3", "Pump_Bay4", "Pump_Bay5", "Pump_Bay6", "Pump_Bay7", "Pump_Bay8" ] interface = syslab.HeatSwitchBoard(_BUILDING_NAME) CompositMess_Shut = CM(_TURN_ME_OFF, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode = PM(_CONSTANT_CURVE, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in pumps: interface.stopPump(pump) interface.setPumpControlMode(pump, mode) time.sleep(0.2) for valve in valves: print("setpoint at 0 for valve", valve) interface.setValvePosition(valve, CompositMess_Shut) time.sleep(0.2)
def PID_controller(self, inputs, process_ID, queue): inputs = pickle.loads(inputs) print(inputs) #inputs = {'controller_name': "['Source_1BH4']['Sink_1DL3']N", 'description': 'creator', # 'gain': '1', 'kp': '4', 'ki': '7', 'kd': '0', 'ki_valve': '0.07', 'pumps_of_circuit': ['Pump_Bay4', 'Pump_Bay3'], # 'circulator': ['Pump_Bay4'], 'circulator_mode': '0', 'actuator': ['Pump_Bay4'], 'setpoint': [4], # 'feedback_sensor': ['Bay_3'], 'valves': ['Bay_4L-Busbar_2R', 'Bay_4H-Busbar_1F', 'Bay_3H-Busbar_2F', 'Bay_3L-Busbar_1R'], # 'secondary_actuators': "Bay_3L-Busbar_1R"} print("Controller Constant Flow Started") interface = syslab.HeatSwitchBoard(_BUILDING_NAME) plt.show() plt.ion() self.xdata = [] self.ydata = [] f, self.ax1 = plt.subplots(1, 1) self.ax1.set_xlim(0, 100) self.ax1.set_ylim(-50, +50) self.ax1.set_xlabel('Time [s]', fontsize=10) self.ax1.set_ylabel('Thermal Power [kW]', fontsize=10) self.line, = self.ax1.plot(self.xdata, self.ydata, 'b-') self.line.set_xdata(self.xdata) self.line.set_ydata(self.ydata) self.plot_array = self.ax1 self.line_array = self.line control_time = 25 start_time = time.time() self.n = 0 self.work_q = queue first_call = True stopper = False active_circuit = True print("Control Process {0} started".format(process_ID)) print("I am process", process_ID) self.process_ID = process_ID max = 100 min = 0 valve_reg = False pumps_of_circuit = inputs["pumps_of_circuit"] kp = float(inputs["kp"]) kd = float(inputs["kd"]) ki = float(inputs["ki"]) ki_valve = float(inputs["ki_valve"]) gain = float(inputs["gain"]) circulators = inputs["circulator"] circulator_mode = int(inputs["circulator_mode"]) circulator_mode_P = 4 print(circulator_mode) feedback_sensor = inputs["feedback_sensor"] feedback_sensor = feedback_sensor[_BEGIN_WITH] actuator_valve = inputs['secondary_actuators'] actuators = inputs["actuator"] valves = inputs["valves"] setpoint = [float(n) for n in inputs["setpoint"]] setpoint = setpoint[_BEGIN_WITH] feedback_value = 0 integral = _MIN_SAT_PUMP integral_valve = 0 controller_output = [_BEGIN_WITH] * len(actuators) controller_output_percentage = [_BEGIN_WITH] * len(actuators) actuator_signal = 0 actuator_signal_valve = 0 error_value = 0 CompositMess = 0 title = "Time Response Signal Sensor " + feedback_sensor self.plot_array.set_title(title) shut_down_signal = 0 shut_mess = CM(shut_down_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode_C = PM(circulator_mode, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) mode_P = PM(circulator_mode_P, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for pump in pumps_of_circuit: if pump not in actuators: print(circulator_mode) interface.setPumpControlMode(pump, mode_C) interface.stopPump(pump) time.sleep(0.2) print("Pump ", pump, "has been stopped") full_power_signal = 100 full_power = CM(full_power_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) print(actuators) n = 0 for pump in actuators: interface.startPump(pump) interface.setPumpControlMode(pump, mode_C) interface.setPumpSetpoint(pump, full_power) time.sleep(0.2) print("Pump ", pump, "was started") n += 1 start_time = time.time() counter_time = time.time() counter_time_valve = time.time() signal.signal(signal.SIGTERM, self.signal_term_handler) time.sleep(30) while (1): try: stop_time = time.time() if (not self.work_q.empty()): received_setpoint = self.work_q.get() setpoint = [float(i) for i in received_setpoint] setpoint = setpoint[_BEGIN_WITH] self.n = 0 print("Control Thread {0} running".format(process_ID)) feedback_value = interface.getThermalPower( feedback_sensor).value if not isinstance(feedback_value, float): feedback_value = 0 # --->>> really bad though print( "feedback taken from sensor {0} with setpoint {1} is kW {2}" .format(feedback_sensor, setpoint, feedback_value)) print("The error is {0}".format(setpoint - feedback_value)) print( "The integral for pump is {0} and the actuator signal for pump is {1}" .format(integral, actuator_signal)) print("The actuator signal for valve is ", actuator_signal_valve) print("Setpoint {0} was sent to actuator {1}".format( actuator_signal, actuators)) print("The current FLow is ", interface.getFlow(feedback_sensor).value) print("The current RPM is ", interface.getPumpRPM("Pump_Bay4").value) print("I am actuating with valve ", valve_reg) self.ydata.append(feedback_value) # Save as previous error. self.xdata.append(time.time() - start_time) #feedback_value[n] = 0 self.update_line() if stop_time - counter_time > control_time: if not valve_reg: print("I am actuating with pump") error_value = setpoint - feedback_value # Calculate the error if abs(error_value) > _FEEDFORWARD_KICK: integral = self.feedforward( interface, setpoint, feedback_sensor, actuators) actuator_signal = integral CompositMess = CM(actuator_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for actuator in actuators: interface.setPumpSetpoint( actuator, CompositMess) else: integral = integral + ki * error_value # Calculate integral integral = self.anti_windup(integral, _PUMP) print("The integral error is ", integral) actuator_signal = kp * error_value + integral actuator_signal = self.saturation( actuator_signal, _PUMP) print("The actuator signal for pump is ", actuator_signal) CompositMess = CM(actuator_signal, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for actuator in actuators: interface.setPumpSetpoint( actuator, CompositMess) counter_time = time.time() if ((error_value < _TOLERANCE) and (actuator_signal <= _MIN_SAT_PUMP) and not valve_reg): print( "I am cheking if is the case of using the valves" ) if first_call: print("60s start from here") start_time = time.time() first_call = False if (time.time() - start_time) >= control_time * 2: print("Time to use the valve") integral_valve = interface.getValvePosition( actuator_valve).value valve_reg = True control_time = 50 pressure_setpoint = 0 pressure_setpoint = CM( pressure_setpoint, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for actuator in actuators: interface.setPumpControlMode( actuator, mode_P) print("Pump {0} was set to {1}".format( actuator, mode_P)) time.sleep(0.2) interface.setPumpSetpoint( actuator, pressure_setpoint) else: counter_time = time.time() first_call = True if valve_reg: print("I am actuating with valve") error_value = setpoint - feedback_value # Calculate the error integral_valve = integral_valve + ki_valve * error_value # Calculate integral integral_valve = self.anti_windup( integral_valve, _VALVE) print("The valve integral error is ", integral_valve) actuator_signal_valve = integral_valve actuator_signal_valve = self.saturation( actuator_signal_valve, _VALVE) print("The actuator signal for valve is ", actuator_signal_valve) CompositMess_Valve = CM(actuator_signal_valve, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) interface.setValvePosition(actuator_valve, CompositMess_Valve) valve_position = interface.getValvePosition( actuator_valve).value #counter_time = time.time() if ((error_value > _TOLERANCE) and (actuator_signal <= _MIN_SAT_PUMP) and (valve_position >= 0.9)): valve_reg = False control_time = 25 first_call = True curve_setpoint = CM(_MIN_SAT_PUMP, time.time() * _MULTIPLIER, _ZERO, _ZERO, _VALIDITY, _SOURCE) for actuator in actuators: interface.setPumpControlMode(actuator, mode_C) time.sleep(0.2) interface.setPumpSetpoint( actuator, curve_setpoint) print("Pump {0} was set to {1}".format( actuator, mode_C)) integral = _MIN_SAT_PUMP else: counter_time = time.time() time.sleep(_ACQUISITION_TIME) except (KeyboardInterrupt, SystemExit): for circulator in circulators: interface.stopPump(pump) print("Circulator {0} is now at zero flow".format( circulator)) sys.exit(0)
import syslab import time import matplotlib.pyplot as plt import syslab.core.datatypes.CompositeMeasurement as CM import syslab.core.datatypes.HeatCirculationPumpMode as PM import pandas as pd import csv _MULTIPLIER = 1000000 _SOURCE = 1 _VALIDITY = 1 _ZERO = 0 _N = 10 interface = syslab.HeatSwitchBoard("716-h1") pump = "Pump_Bay4" constant_pressure = 3 start_time = time.time() pump_head_response = [] pump_rpm_response = [] pump_flow_response = [] sensor_power_response = [] sensor_flow_response = [] total_flow_response = [] total_power_response = [] sensor_power_response_2 = [] sensor_flow_response_2 = [] valve_position = [] valve_position_2 = [] time_passed = []