def run(self, cur_time, points): """ Sends device points to Matlab application and waits for response. Creates and returns Results object from received response from Matlab application. :param cur_time: timestamp :param points: device point name and value :type cur_time: datetime.datetime :type points: dict :Returns Results object containing commands for devices, log messages and table data. :rtype results: Results object \\volttron.platform.agent.driven""" try: self.data_socket.send_pyobj(points,zmq.NOBLOCK) except zmq.error.ZMQError: print("No Matlab process running to send message. Exiting.") print("Waiting for matlab results") event = self.data_socket.poll(self.recv_timeout) if event > 0: matlab_result = self.data_socket.recv_json() matlab_result = eval(matlab_result) result = Results() if 'commands' in matlab_result: commands = matlab_result['commands'] for device, point_value_dict in commands.items(): for point, value in point_value_dict: result.command(point, value, device); if 'logs' in matlab_result: logs = matlab_result['logs'] for message in logs: result.log(message); if 'table_data' in matlab_result: table_data = matlab_result['table_data'] for table in table_data: rows = table_data[table] for row in rows: result.insert_table_row(table, row) return result
def run(self, cur_time, points): """ Main run method that is called by the DrivenBaseClass. run receives a dictionary of data 'points' and an associated timestamp for the data cur_time'. run then passes the appropriate data to each diagnostic when calling the diagnostic message. :param cur_time: :param points: :return: """ device_dict = {} dx_result = Results() for point, value in points.items(): point_device = [name.lower() for name in point.split("&")] if point_device[0] not in device_dict: device_dict[point_device[0]] = [(point_device[1], value)] else: device_dict[point_device[0]].append((point_device[1], value)) damper_data = [] oat_data = [] mat_data = [] rat_data = [] cooling_data = [] fan_sp_data = [] fan_status_data = [] missing_data = [] for key, value in device_dict.items(): data_name = key if value is None: continue if data_name == self.fan_status_name: fan_status_data = data_builder(value, data_name) elif data_name == self.oad_sig_name: damper_data = data_builder(value, data_name) elif data_name == self.oat_name: oat_data = data_builder(value, data_name) elif data_name == self.mat_name: mat_data = data_builder(value, data_name) elif data_name == self.rat_name: rat_data = data_builder(value, data_name) elif data_name == self.cool_call_name: cooling_data = data_builder(value, data_name) elif data_name == self.fan_sp_name: fan_sp_data = data_builder(value, data_name) if not oat_data: missing_data.append(self.oat_name) if not rat_data: missing_data.append(self.rat_name) if not mat_data: missing_data.append(self.mat_name) if not damper_data: missing_data.append(self.oad_sig_name) if not cooling_data: missing_data.append(self.cool_call_name) if not fan_status_data and not fan_sp_data: missing_data.append(self.fan_status_name) if missing_data: dx_result.log("Missing data from publish: {}".format(missing_data)) return dx_result current_fan_status, fan_sp = self.check_fan_status( fan_status_data, fan_sp_data, cur_time) dx_result = self.check_elapsed_time(dx_result, cur_time, self.unit_status, FAN_OFF) if not current_fan_status: dx_result.log("Supply fan is off: {}".format(cur_time)) return dx_result else: dx_result.log("Supply fan is on: {}".format(cur_time)) if fan_sp is None and self.constant_volume: fan_sp = 100.0 oat = mean(oat_data) rat = mean(rat_data) mat = mean(mat_data) oad = mean(damper_data) self.check_temperature_condition(oat, rat, cur_time) dx_result = self.check_elapsed_time(dx_result, cur_time, self.oaf_condition, OAF) if self.oaf_condition: dx_result.log("OAT and RAT readings are too close.") return dx_result limit_condition = self.sensor_limit_check(oat, rat, mat, cur_time) dx_result = self.check_elapsed_time(dx_result, cur_time, self.sensor_limit, limit_condition[1]) if limit_condition[0]: dx_result.log( "Temperature sensor is outside of bounds: {} -- {}".format( limit_condition, self.sensor_limit)) return dx_result dx_result, self.temp_sensor_problem = self.econ1.econ_alg1( dx_result, oat, rat, mat, oad, cur_time) econ_condition, cool_call = self.determine_cooling_condition( cooling_data, oat, rat) _log.debug("Cool call: {} - Economizer status: {}".format( cool_call, econ_condition)) if self.temp_sensor_problem is not None and not self.temp_sensor_problem: dx_result = self.econ2.econ_alg2(dx_result, cool_call, oat, rat, mat, oad, econ_condition, cur_time, fan_sp) dx_result = self.econ3.econ_alg3(dx_result, oat, rat, mat, oad, econ_condition, cur_time, fan_sp) dx_result = self.econ4.econ_alg4(dx_result, oat, rat, mat, oad, econ_condition, cur_time, fan_sp) dx_result = self.econ5.econ_alg5(dx_result, oat, rat, mat, cur_time) elif self.temp_sensor_problem: self.pre_conditions(dx_list[1:], TEMP_SENSOR, cur_time, dx_result) self.econ2.clear_data() self.econ2.clear_data() self.econ3.clear_data() self.econ4.clear_data() self.econ5.clear_data() return dx_result
def run(self, cur_time, points): device_dict = {} dx_result = Results() fan_status_data = [] supply_fan_off = False low_dx_cond = False high_dx_cond = False for key, value in points.items(): point_device = [_name.lower() for _name in key.split('&')] if point_device[0] not in device_dict: device_dict[point_device[0]] = [(point_device[1], value)] else: device_dict[point_device[0]].append((point_device[1], value)) if self.fan_status_name in device_dict: fan_status = device_dict[self.fan_status_name] fan_status = [point[1] for point in fan_status] fan_status = [status for status in fan_status if status is not None] if fan_status_data: fan_status_data.append(min(fan_status)) if not int(fan_status_data[0]): supply_fan_off = True self.warm_up_flag = True if self.fansp_name in device_dict: fan_speed = device_dict[self.fansp_name] fan_speed = mean([point[1] for point in fan_speed]) if self.fan_status_name is None: if not int(fan_speed): supply_fan_off = True self.warm_up_flag = True fan_status_data.append(bool(int(fan_speed))) if fan_speed > self.high_sf_threshold: low_dx_cond = True elif fan_speed < self.low_sf_threshold: high_dx_cond = True stc_pr_data = [] stcpr_sp_data = [] zn_dmpr_data = [] satemp_data = [] rht_data = [] sat_stpt_data = [] validate = {} sched_val = {} def validate_builder(value_tuple, point_name): value_list = [] for item in value_tuple: tag = item[0] + '/' + point_name validate.update({tag: item[1]}) value_list.append(item[1]) return value_list for key, value in device_dict.items(): data_name = key if value is None: continue if data_name == self.duct_stp_stpt_name: stcpr_sp_data = validate_builder(value, data_name) sched_val.update(validate) elif data_name == self.sat_stpt_name: sat_stpt_data = validate_builder(value, data_name) sched_val.update(validate) elif data_name == self.duct_stp_name: sched_val.update(validate) stc_pr_data = validate_builder(value, data_name) sched_val.update(validate) elif data_name == self.sa_temp_name: satemp_data = validate_builder(value, data_name) sched_val.update(validate) elif data_name == self.zone_reheat_name: rht_data = validate_builder(value, data_name) elif data_name == self.zone_damper_name: zn_dmpr_data = validate_builder(value, data_name) missing_data = [] if not satemp_data: missing_data.append(self.sa_temp_name) if not rht_data: missing_data.append(self.zone_reheat_name) if not sat_stpt_data: dx_result.log('Supply-air temperature set point data is ' 'missing. This will limit the effectiveness of ' 'the supply-air temperature diagnostics.') if not stc_pr_data: missing_data.append(self.duct_stp_name) if not stcpr_sp_data: dx_result.log('Duct static pressure set point data is ' 'missing. This will limit the effectiveness of ' 'the duct static pressure diagnostics.') if not zn_dmpr_data: missing_data.append(self.zone_damper_name) if not fan_status: missing_data.append(self.fan_status_name) if missing_data: raise Exception('Missing required data: {}'.format(missing_data)) return dx_result dx_result = ( self.sched_occ_dx.sched_rcx_alg(cur_time, stc_pr_data, stcpr_sp_data, sat_stpt_data, fan_status, dx_result, sched_val)) if supply_fan_off: dx_result.log('Supply fan is off. Data will not be used for ' 'retuning diagnostics.') return dx_result if self.warm_up_flag: self.warm_up_flag = False self.warm_up_start = cur_time return dx_result time_check = td(minutes=self.warm_up_time) if (self.warm_up_start is not None and (cur_time - self.warm_up_start) < time_check): dx_result.log('Unit is in warm-up. Data will not be analyzed.') return dx_result dx_result = ( self.static_dx.duct_static(cur_time, stcpr_sp_data, stc_pr_data, zn_dmpr_data, low_dx_cond, high_dx_cond, dx_result, validate)) dx_result = ( self.sat_dx.sat_rcx(cur_time, satemp_data, sat_stpt_data, rht_data, zn_dmpr_data, dx_result, validate)) return dx_result
def run(self, cur_time, points): device_dict = {} dx_result = Results() for key, value in points.items(): point_device = [_name for _name in key.split("&")] if point_device[0] not in device_dict: device_dict[point_device[0]] = [(point_device[1], value)] else: device_dict[point_device[0]].append((point_device[1], value)) fan_status_data = [] stcpr_stpt_data = [] stc_pr_data = [] sat_stpt_data = [] sat_data = [] zn_rht_data = [] zn_dmpr_data = [] fan_sp_data = [] for key, value in device_dict.items(): data_name = key if value is None: continue if data_name == self.fan_status_name: fan_status_data = data_builder(value, data_name) elif data_name == self.duct_stp_stpt_name: stcpr_stpt_data = data_builder(value, data_name) elif data_name == self.duct_stp_name: stc_pr_data = data_builder(value, data_name) elif data_name == self.sat_stpt_name: sat_stpt_data = data_builder(value, data_name) elif data_name == self.sa_temp_name: sat_data = data_builder(value, data_name) elif data_name == self.zn_reheat_name: zn_rht_data = data_builder(value, data_name) elif data_name == self.zn_damper_name: zn_dmpr_data = data_builder(value, data_name) elif data_name == self.fan_sp_name: fan_sp_data = data_builder(value, data_name) missing_data = [] if not fan_status_data and not fan_sp_data: missing_data.append(self.fan_status_name) if not sat_data: missing_data.append(self.sa_temp_name) if not zn_rht_data: missing_data.append(self.zn_reheat_name) if not sat_stpt_data: dx_result.log("SAT set point data is missing.") if not stc_pr_data: missing_data.append(self.duct_stp_name) if not stcpr_stpt_data: dx_result.log("Duct static pressure set point data is missing.") if not zn_dmpr_data: missing_data.append(self.zn_damper_name) if missing_data: dx_result.log("Missing data from publish: {}".format(missing_data)) return dx_result current_fan_status, fan_sp = self.check_fan_status( fan_status_data, fan_sp_data, cur_time) dx_result = self.sched_reset_aircx.schedule_reset_aircx( cur_time, stc_pr_data, stcpr_stpt_data, sat_stpt_data, current_fan_status, dx_result) dx_result = self.check_elapsed_time(dx_result, cur_time, self.unit_status, FAN_OFF) if not current_fan_status: dx_result.log("Supply fan is off: {}".format(cur_time)) self.warm_up_flag = True return dx_result dx_result.log("Supply fan is on: {}".format(cur_time)) low_sf_cond = True if fan_sp is not None and fan_sp > self.high_sf_thr else False high_sf_cond = True if fan_sp is not None and fan_sp < self.low_sf_thr else False if self.warm_up_flag: self.warm_up_flag = False self.warm_up_start = cur_time return dx_result if self.warm_up_start is not None and ( cur_time - self.warm_up_start) < self.warm_up_time: dx_result.log("Unit is in warm-up. Data will not be analyzed.") return dx_result dx_result = self.stcpr_aircx.stcpr_aircx(cur_time, stcpr_stpt_data, stc_pr_data, zn_dmpr_data, low_sf_cond, high_sf_cond, dx_result) dx_result = self.sat_aircx.sat_aircx(cur_time, sat_data, sat_stpt_data, zn_rht_data, zn_dmpr_data, dx_result) return dx_result
def run(self, cur_time, points): '''Main run method that is called by the DrivenBaseClass. run receives a dictionary of data 'points' and an associated timestamp for the data cur_time'. run then passes the appropriate data to each diagnostic when calling the diagnostic message. ''' validate_topic = create_table_key('validate', cur_time) validate_data = {ECON1: 3, ECON2: 3, ECON3: 3, ECON4: 3, ECON5: 3} try: device_dict = {} dx_result = Results() fan_status_data = [] supply_fan_off = False for key, value in points.items(): point_device = [_name.lower() for _name in key.split('&')] if point_device[0] not in device_dict: device_dict[point_device[0]] = [(point_device[1], value)] else: device_dict[point_device[0]].append( (point_device[1], value)) if self.fan_status_name in device_dict: fan_status = device_dict[self.fan_status_name] fan_status = [point[1] for point in fan_status] fan_status = [ status for status in fan_status if status is not None ] if fan_status_data: fan_status_data.append(min(fan_status)) if not int(fan_status_data[0]): supply_fan_off = True self.warm_up_flag = True if self.fansp_name in device_dict: fan_speed = device_dict[self.fansp_name] fan_speedcmd = mean([point[1] for point in fan_speed]) if self.fan_status_name is None: if not int(fan_speedcmd): supply_fan_off = True self.warm_up_flag = True fan_status_data.append(bool(int(fan_speedcmd))) if fan_speedcmd < self.low_supply_fan_threshold: _log.debug( 'Fan is operating below minimum configured speed.') return dx_result if supply_fan_off: dx_result.log( 'Supply fan is off. Data will not be used for retuning diagnostics.' ) damper_data = [] oat_data = [] mat_data = [] rat_data = [] cooling_data = [] fan_sp_data = [] def data_builder(value_tuple, point_name): value_list = [] for item in value_tuple: value_list.append(item[1]) return value_list for key, value in device_dict.items(): data_name = key if value is None: continue if data_name == self.oad_sig_name: damper_data = data_builder(value, data_name) elif data_name == self.oat_name: oat_data = data_builder(value, data_name) elif data_name == self.mat_name: mat_data = data_builder(value, data_name) elif data_name == self.rat_name: rat_data = data_builder(value, data_name) elif data_name == self.cool_call_name: cooling_data = data_builder(value, data_name) elif data_name == self.fan_sp_name: fan_sp_data = data_builder(value, data_name) missing_data = [] if not oat_data: missing_data.append(self.oat_name) if not rat_data: missing_data.append(self.rat_name) if not mat_data: missing_data.append(self.mat_name) if not damper_data: missing_data.append(self.oad_sig_name) if not cooling_data: missing_data.append(self.cool_call_name) if missing_data: dx_result.log('Missing required data: {}'.format(missing_data)) return dx_result oatemp = (sum(oat_data) / len(oat_data)) ratemp = (sum(rat_data) / len(rat_data)) matemp = (sum(mat_data) / len(mat_data)) damper_signal = (sum(damper_data) / len(damper_data)) fan_speedcmd = None if fan_sp_data: fan_speedcmd = sum(fan_sp_data) / len(fan_sp_data) limit_check = False if oatemp < self.oat_low_threshold or oatemp > self.oat_high_threshold: dx_result.log('Outside-air temperature is outside high/low ' 'operating limits, check the functionality of ' 'the temperature sensor.') limit_check = True if ratemp < self.rat_low_threshold or ratemp > self.rat_high_threshold: dx_result.log('Return-air temperature is outside high/low ' 'operating limits, check the functionality of ' 'the temperature sensor.') limit_check = True if matemp < self.mat_low_threshold or matemp > self.mat_high_threshold: dx_result.log('Mixed-air temperature is outside high/low ' 'operating limits, check the functionality ' 'of the temperature sensor.') limit_check = True if limit_check: return dx_result if abs(oatemp - ratemp) < self.oaf_temperature_threshold: dx_result.log( 'OAT and RAT are too close, economizer diagnostic ' 'will not use data corresponding to: {timestamp} '.format( timestamp=str(cur_time)), logging.DEBUG) return dx_result device_type_error = False if self.device_type == 'ahu': cooling_valve = sum(cooling_data) / len(cooling_data) if cooling_valve > self.cooling_enabled_threshold: cooling_call = True else: cooling_call = False elif self.device_type == 'rtu': cooling_call = int(max(cooling_data)) else: device_type_error = True dx_result.log( 'device_type must be specified as "AHU" or "RTU" ' 'Check Configuration input.', logging.INFO) if device_type_error: return dx_result if self.economizer_type == 'ddb': econ_condition = oatemp < (ratemp - self.temp_deadband) else: econ_condition = oatemp < (self.econ_hl_temp - self.temp_deadband) dx_result.log( 'Debugger - econmizer status {}'.format(econ_condition)) dx_result, dx_status = self.econ1.econ_alg1( dx_result, oatemp, ratemp, matemp, damper_signal, cur_time) validate_data.update({ECON1: dx_status}) dx_result.log('Debugger - Temperature sensor flag: {}'.format( TempSensorDx.temp_sensor_problem)) if TempSensorDx.temp_sensor_problem is not None and TempSensorDx.temp_sensor_problem is False: dx_result, dx_status = self.econ2.econ_alg2( dx_result, cooling_call, oatemp, ratemp, matemp, damper_signal, econ_condition, cur_time, fan_speedcmd) validate_data.update({ECON2: dx_status}) dx_result, dx_status = self.econ3.econ_alg3( dx_result, oatemp, ratemp, matemp, damper_signal, econ_condition, cur_time, fan_speedcmd, cooling_call) validate_data.update({ECON3: dx_status}) dx_result, dx_status = self.econ4.econ_alg4( dx_result, oatemp, ratemp, matemp, damper_signal, econ_condition, cur_time, fan_speedcmd, cooling_call) validate_data.update({ECON4: dx_status}) dx_result, dx_status = self.econ5.econ_alg5( dx_result, oatemp, ratemp, matemp, damper_signal, econ_condition, cur_time, cooling_call) validate_data.update({ECON5: dx_status}) else: dx_result = self.econ2.clear_data(dx_result) dx_result = self.econ3.clear_data(dx_result) dx_result = self.econ4.clear_data(dx_result) dx_result = self.econ5.clear_data(dx_result) TempSensorDx.temp_sensor_problem = None return dx_result finally: dx_result.insert_table_row(validate_topic, validate_data)