diff --git a/PowerDiagram.py b/PowerDiagram.py index d3d2488..a529f46 100644 --- a/PowerDiagram.py +++ b/PowerDiagram.py @@ -269,13 +269,21 @@ class PowerConfig(object): except TableAttrNotFound: pass - if re.match('[a-z]+.._..', machine_name): + num_machines = 1 + match = re.match(r'(?P[a-z]+)(?P[0-9]+)_(?P[0-9]+)', machine_name) + if match: # machine_name is a group of machines such as physix80_83 # in this case, we use a hack : the type and power consumption is based on the first machine of this group (in this example physix80) - machine_name = '_'.join(machine_name.split('_')[0:-1]) + # machine_name = '_'.join(machine_name.split('_')[0:-1]) + print('machine_name = %s' % machine_name) + first_index = int(match.group('first_index')) + last_index = int(match.group('last_index')) + machine_name = '%s%02d' % (match.group('cluster_name'), first_index) + num_machines = last_index - first_index + 1 # print(machine_name) + # find the max power consumption of this machine machine_spec_id = None try: # assert machine_spec_id != '', 'non-empty value expected for machine_spec_id for machine %s' % machine_name @@ -286,9 +294,23 @@ class PowerConfig(object): pass if machine_spec_id is not None: - power_consumption = inventory.machine_spec_id_to_power_consumption(machine_spec_id) - if power_consumption is not None: - machine.power_consumption = power_consumption + measured_max_power_consumption = inventory.machine_to_power_consumption(machine_name) + estimated_max_power_consumption = None + chassis_power_consumption = inventory.machine_spec_id_to_power_consumption(machine_spec_id) + if chassis_power_consumption is not None: + estimated_max_power_consumption = chassis_power_consumption + try: + cpu_power_consumption = inventory.get_num_cpus(machine_name) * inventory.get_cpu_tdp(machine_name) + estimated_max_power_consumption += cpu_power_consumption + except TableAttrNotFound as e: # noqa: F841 + pass # could happen for machines that have no cpu (eg simpa-switch-cisco-2) + if measured_max_power_consumption is not None: + machine.power_consumption = num_machines * measured_max_power_consumption + if estimated_max_power_consumption is not None: + # assert measured_max_power_consumption > estimated_max_power_consumption, 'the estimated power consumption (%f W) of %s is too far from is measured value (%f W)' % (estimated_max_power_consumption, machine_name, measured_max_power_consumption) + pass + elif estimated_max_power_consumption is not None: + machine.power_consumption = num_machines * estimated_max_power_consumption def get_connection_to(self, to_plug): for connection in self.connections: diff --git a/inventory.py b/inventory.py index 8a0f977..afe574e 100644 --- a/inventory.py +++ b/inventory.py @@ -64,6 +64,14 @@ class Inventory(object): power_consumption = 0.0 return power_consumption + def machine_to_power_consumption(self, machine_id): + try: + power_consumption = float(self._sql_reader.get_table_attr('machine_to_power_consumption', 'machine_id', machine_id, 'power_consumption')) + except SimpaDbUtil.TableAttrNotFound as e: # noqa: F841 @UnusedVariable + # some passive machines such as pdus are not detailed in the machine_spec_to_power_consumption because they don't consume power + power_consumption = None + return power_consumption + def get_plug_type_attr(self, plug_type, attr_name): """ :param str plug_type: eg 'c14' @@ -161,6 +169,10 @@ class Inventory(object): cpu_model = self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'cpu_model') return float(self._sql_reader.get_table_attr('cpu_specs', 'cpu_model', cpu_model, 'clock_speed')) + def get_cpu_tdp(self, computer_name): + cpu_model = self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'cpu_model') + return float(self._sql_reader.get_table_attr('cpu_specs', 'cpu_model', cpu_model, 'tdp')) + def get_computer_dflops(self, computer_name): # print(computer_serial_number) num_cpus = int(self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'num_cpu'))