From 82816e51936a47deff4958c1480d7ac07f051883 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Thu, 21 Jan 2021 16:14:29 +0000 Subject: [PATCH] just fixed pylint warnings and errors --- PowerDiagram.py | 51 +++++++++++++++++++++++++------------------------ inventory.py | 38 ++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/PowerDiagram.py b/PowerDiagram.py index def3298..d3d2488 100644 --- a/PowerDiagram.py +++ b/PowerDiagram.py @@ -2,7 +2,7 @@ The goal of this application is to generate a power diagram that will help system administrators to: - document the power supply architecture - easily spot potential power overloads (for example if the power consumption exceeds the capacity of a cable) - + This application takes its input from a database, currently in the form of an sql dump, but it could easily be adapted to read directly from a mysql database ''' @@ -16,7 +16,7 @@ from SimpaDbUtil import SqlFile, SqlDatabaseReader, TableAttrNotFound def add_capacity_constraints(capacity1, capacity2): """ combines 2 capacity constraints (max amperes) together - + :param float capacity1: max amperes for the first capacity, None if there are no constraints :param float capacity2: max amperes for the second capacity, None if there are no constraints :return float: max amperes for the combined capacity, None if there are no constraints @@ -95,7 +95,6 @@ class Machine(object): return self.name == 'edf' or re.match('^ups[0-9]*$', self.name) - class Plug(object): """ represents a power plug (input or output) of a device @@ -131,20 +130,21 @@ class Plug(object): # apply incoming connection amperes limitation capacity = add_capacity_constraints(capacity, in_con.get_max_amperes()) if debug: - print(str(self)+ 'after incoming connection amperes limitation, capacity = ' + str(capacity)) + print(str(self) + 'after incoming connection amperes limitation, capacity = ' + str(capacity)) else: # apply the machine containing this plug's amperes limitation capacity = add_capacity_constraints(capacity, self.machine.get_max_amperes()) if debug: - print(str(self)+'apply the machine containing this plug s amperes limitation, capacity = ' + str(capacity)) - + print(str(self) + 'apply the machine containing this plug s amperes limitation, capacity = ' + str(capacity)) + # apply this plug's amperes limitation capacity = add_capacity_constraints(capacity, self.current_capacity_constraint) if debug: - print(str(self)+'after apply this plug s amperes limitation, capacity = ' + str(capacity), self.current_capacity_constraint) + print(str(self) + 'after apply this plug s amperes limitation, capacity = ' + str(capacity), self.current_capacity_constraint) return capacity + class Connection(object): """ a power cable connecting an input power plug to an output power plug @@ -157,7 +157,7 @@ class Connection(object): def __str__(self): return str(self.from_plug) + ' -> ' + str(self.to_plug) + ' (' + str(self.from_plug.get_max_amperes()) + ' A, ' + str(self.get_max_amperes()) + ' A)' - + def get_max_amperes(self): # gLogger.debug('%s (%s A) -> %s (%s A): ' % (str(self.from_plug), str(self.from_plug.get_max_amperes()), str(self.to_plug), str(self.to_plug.current_capacity_constraint))) capacity = self.from_plug.get_max_amperes() @@ -203,7 +203,7 @@ class Connection(object): to_machine = self.to_plug.machine power_consumption = None if worst_case_scenario: - if False: # self.is_redundancy_cable(): + if False: # self.is_redundancy_cable(): power_consumption = 0.0 else: power_consumption = to_machine.get_power_consumption(worst_case_scenario) @@ -217,6 +217,7 @@ class Connection(object): power_consumption = to_machine.get_power_consumption(worst_case_scenario) / num_input_cables return power_consumption + class PowerConfig(object): """ the description of how machines are connected together (in terms of electric power) @@ -225,17 +226,17 @@ class PowerConfig(object): def __init__(self, simpa_db_sql_file_path): self.machines = {} self.connections = [] - + sql_source = SqlFile(simpa_db_sql_file_path) sql_reader = SqlDatabaseReader(sql_source) inventory = Inventory(sql_reader) self._parse_from_inventory(inventory) - + def _parse_from_inventory(self, inventory): """ :param Inventory inventory: """ - + rows = inventory.query("SELECT * FROM machine_to_power") for row in rows: @@ -255,7 +256,7 @@ class PowerConfig(object): (to_plug_as_str, max_amps_as_str) = row to_plug = self._get_plug(to_plug_as_str) to_plug.set_current_capacity_constraint(float(max_amps_as_str)) - + for machine in self.machines.values(): machine_name = machine.name @@ -283,13 +284,12 @@ class PowerConfig(object): machine_spec_id = None # some simple 'machines' such as powerext003 have undefined machine_spec_id except MachineSpecIdNotFound: 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 - def get_connection_to(self, to_plug): for connection in self.connections: if connection.to_plug == to_plug: @@ -300,27 +300,28 @@ class PowerConfig(object): if machine_name not in self.machines: self.machines[machine_name] = Machine(machine_name, self) return self.machines[machine_name] - + def _get_plug(self, plug_as_str): elements = plug_as_str.split('_') plug_name = elements[-1] machine_name = plug_as_str[0:-(len(plug_name) + 1)] machine = self._get_machine(machine_name) return machine.get_plug(plug_name) - + def _add_connection(self, from_plug_as_str, to_plug_as_str): from_plug = self._get_plug(from_plug_as_str) to_plug = self._get_plug(to_plug_as_str) conn = Connection(from_plug, to_plug) self.connections.append(conn) return conn - + def __str__(self): s = '' for c in self.connections: s += str(c) + '\n' return s + class CableColorer(object): def get_cable_color(self, cable, worst_case_scenario): @@ -329,6 +330,7 @@ class CableColorer(object): """ raise NotImplementedError + class SimpleColorer(CableColorer): def get_cable_color(self, cable, worst_case_scenario): @@ -349,6 +351,7 @@ class SimpleColorer(CableColorer): color = '/svg/green' return color + class RampColorer(CableColorer): @staticmethod @@ -384,24 +387,24 @@ class RampColorer(CableColorer): color = '/svg/red' # draw overloaded cables in red return color + def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True): """ creates a svg diagram representing the input power configuration - + :param PowerConfig power_config: the input power config """ graph = pygraphviz.AGraph(strict=False) # strict=False allows more than one connection between 2 nodes graph.graph_attr['overlap'] = 'false' graph.graph_attr['splines'] = 'true' graph.graph_attr['rankdir'] = 'LR' # to get hrizontal tree rather than vertical - + graph.edge_attr['colorscheme'] = 'rdylgn9' # 'brbg11' graph.node_attr['shape'] = 'box' graph.node_attr['height'] = 0.3 # default 0.5 inches graph.node_attr['fontname'] = 'Helvetica' # default : Times-Roman graph.edge_attr['fontsize'] = 10 # default : 14 pt graph.edge_attr['len'] = 1.5 # default : 1.0 - # graph.add_node('a') # graph.add_node('b') @@ -438,7 +441,6 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True): \ >' % (machine.name, machine_total_power_consumption) - if False: x = 0.0 for rack in racks.itervalues(): @@ -470,7 +472,7 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True): penwidth = capacity * penwidth_scaler label = "%.1f/%s" % (amperes, max_amp) # color='//%d' % int(9.0-amperes/capacity*8) - + # graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color="%s:%s" % (color, wsc_color), label=label, penwidth="%s:%s" % (penwidth, penwidth)) graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=penwidth) @@ -481,10 +483,9 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True): sub.graph_attr['label'] = rack_id # sub.graph_attr['rank']='same' # assert False - #graph.layout(prog='twopi') + # graph.layout(prog='twopi') with open('./toto.dot', 'w') as f: f.write(graph.string()) - graph.layout(prog='dot') graph.draw(svg_file_path) diff --git a/inventory.py b/inventory.py index 1fc0046..8a0f977 100644 --- a/inventory.py +++ b/inventory.py @@ -1,6 +1,6 @@ # encoding: utf-8 import datetime -#from Lib import SimpaDbUtil +# from Lib import SimpaDbUtil import SimpaDbUtil @@ -20,14 +20,14 @@ class PlugTypeNotFound(Exception): class Inventory(object): - + def __init__(self, sql_reader): """ :param SimpaDbUtil.SqlDatabaseReader sql_reader: the inventory database """ super(Inventory, self).__init__() self._sql_reader = sql_reader - + def query(self, sql_query): return self._sql_reader.query(sql_query) @@ -48,7 +48,7 @@ class Inventory(object): def machine_name_to_machine_spec_id(self, machine_name): try: machine_spec_id = self._sql_reader.get_table_attr('machines', 'name', machine_name, 'machine_spec_id') - except SimpaDbUtil.TableAttrNotFound as e: # @UnusedVariable + except SimpaDbUtil.TableAttrNotFound as e: # noqa: F841 @UnusedVariable raise MachineSpecIdNotFound(machine_name) if machine_spec_id == '': raise MachineSpecIdNotFound(machine_name) @@ -59,7 +59,7 @@ class Inventory(object): def machine_spec_id_to_power_consumption(self, machine_spec_id): try: power_consumption = float(self._sql_reader.get_table_attr('machine_spec_to_power_consumption', 'machine_spec_id', machine_spec_id, 'power_consumption')) - except SimpaDbUtil.TableAttrNotFound as e: # @UnusedVariable + 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 = 0.0 return power_consumption @@ -72,7 +72,7 @@ class Inventory(object): # ('iec60309_blue_pne6h_32a_m', 'm', 32.0), attr_value = self._sql_reader.get_table_attr('powerplug_type_desc', 'plug_type_id', plug_type, attr_name) return attr_value - + def get_plug_type(self, machine_name, plug_name): """ :param str machine_name: eg 'pdu4' @@ -92,7 +92,7 @@ class Inventory(object): else: raise PlugTypeNotFound(machine_spec_id, plug_name) return plug_type - + def read_plug_capacity(self, plug): """ :param PowerDiagram.Plug plug: the power plug of a 'device' we're interested in (eg pdu4.o1) @@ -105,12 +105,12 @@ class Inventory(object): except MachineSpecIdNotFound: # some machines are not actual machines (eg edf, ups1pdu) pass - #except PlugTypeNotFound: + # except PlugTypeNotFound: # some plugs are just plain connections, with no actual plug types # pass if plug_type is not None: # print('plug_type : %s' % plug_type) - + plug_capacity = self.get_plug_type_attr(plug_type, 'max_amps') # if plug_capacity: # print('plug_capacity : %f A' % plug_capacity) @@ -150,7 +150,7 @@ class Inventory(object): dflops_per_core_per_cycle = int(self._sql_reader.get_table_attr('cpu_specs', 'cpu_model', cpu_model, 'dflops_per_core_per_cycle')) # print(num_cores, clock_speed, dflops_per_core_per_cycle) return clock_speed * dflops_per_core_per_cycle * num_cores - + def get_num_cpus(self, computer_name): return int(self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'num_cpu')) @@ -160,20 +160,20 @@ class Inventory(object): def get_cpu_frequency(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, 'clock_speed')) - + 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')) + num_cpus = int(self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'num_cpu')) cpu_model = self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'cpu_model') flops = num_cpus * self.get_cpu_dflops(cpu_model) return flops - + def get_computer_options_price(self, computer_name): options_price = 0.0 if computer_name == 'simpatix58' or computer_name == 'simpatix59': return 7675.0 / 4 * 2 # each of these computers has 2 nvidia fermi C2050 gpus return options_price - + def get_item_container(self, item_id): """ :param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.) @@ -184,7 +184,7 @@ class Inventory(object): if len(rows) > 0: container_id = rows[0][0] return container_id - + def get_item_price(self, item_id, include_contents=False, include_maintenance=False): """ :param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.) @@ -201,7 +201,7 @@ class Inventory(object): for row in rows: maintenance_price_ex_vat = float(row[0]) item_price += maintenance_price_ex_vat - + if include_contents: # add the price of included parts rows = self._sql_reader.query("SELECT part_id FROM container WHERE container_id='%s'" % item_id) @@ -210,10 +210,10 @@ class Inventory(object): item_price += self.get_item_price(part_id, include_contents, include_maintenance) # print(u'price of %s : %.2f € HT' % (item_id, item_price)) return item_price - + def get_item_ownership(self, item_id): ownership = [] - + rows = self._sql_reader.query("SELECT * FROM ownership WHERE machine_id='%s'" % item_id) for row in rows: (machine_id, owner, owner_ratio, comment) = row # @UnusedVariable @@ -222,7 +222,7 @@ class Inventory(object): def get_item_use(self, item_id): ownership = [] - + rows = self._sql_reader.query("SELECT * FROM machine_users") for row in rows: (machine_id, user, user_ratio, comment) = row # @UnusedVariable