Esempio n. 1
0
 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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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)