From a2be664bbec99f0506edb41cf29bb5313853b1d1 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Tue, 28 Aug 2018 13:27:29 +0000 Subject: [PATCH] Bug 2412 - la page cluster/UserGuide ne fonctionne plus - for the sake of debugging, improved the handling of missing data in SimpaDb.sql : now when a data is missing, the exception handler displays a message describing what's missing. --- PowerDiagram.py | 26 +++++++++++++---- SimpaDbUtil.py | 14 +++++++++- inventory.py | 74 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 93 insertions(+), 21 deletions(-) diff --git a/PowerDiagram.py b/PowerDiagram.py index 7fafd37..6deca1b 100644 --- a/PowerDiagram.py +++ b/PowerDiagram.py @@ -10,6 +10,7 @@ import re import pygraphviz from inventory import Inventory from SimpaDbUtil import SqlFile, SqlDatabaseReader +from Lib import SimpaDbUtil def add_capacity_constraints(capacity1, capacity2): @@ -136,6 +137,7 @@ class Connection(object): return str(self.from_plug) + ' -> ' + str(self.to_plug) + ' (' + str(self.from_plug.get_max_amperes()) + 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() capacity = add_capacity_constraints(capacity, self.to_plug.current_capacity_constraint) if self.current_capacity_constraint is not None: @@ -202,7 +204,15 @@ class PowerConfig(object): # print(machine_name) - machine_spec_id = inventory.machine_name_to_machine_spec_id(machine_name) + machine_spec_id = None + try: + # assert machine_spec_id != '', 'non-empty value expected for machine_spec_id for machine %s' % machine_name + machine_spec_id = inventory.machine_name_to_machine_spec_id(machine_name) + if machine_spec_id == '': + machine_spec_id = None # some simple 'machines' such as powerext003 have undefined machine_spec_id + except SimpaDbUtil.TableAttrNotFound: + 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: @@ -275,20 +285,24 @@ def power_config_to_svg(power_config, svg_file_path): amperes = power_consumption / 220.0 color = 'green' capacity = con.get_max_amperes() + penwidth_scaler = 0.25 if capacity is None: - label = '?' + max_amp = '? A' + color = 'red' + penwidth = 100.0 * penwidth_scaler # make the problem clearly visible else: - label = str(capacity) + 'A' + max_amp = str(capacity) + 'A' if amperes / capacity > 1.0: color = 'red' elif amperes / capacity > 0.75: color = 'orange' else: color = 'green' - label = "%.1f/%s" % (amperes, label) + color = hotness_to_hsv_color(pow(amperes / capacity, 4.0)) + penwidth = capacity * penwidth_scaler + label = "%.1f/%s" % (amperes, max_amp) # color='//%d' % int(9.0-amperes/capacity*8) - color = hotness_to_hsv_color(pow(amperes / capacity, 4.0)) - graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=capacity * 0.25) + graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=penwidth) graph.layout(prog='twopi') graph.draw(svg_file_path) diff --git a/SimpaDbUtil.py b/SimpaDbUtil.py index 5d2a967..118f1bc 100644 --- a/SimpaDbUtil.py +++ b/SimpaDbUtil.py @@ -112,7 +112,17 @@ class SqlFile(ISqlDatabaseBackend): rows = self._cur.fetchall() return rows - + +class TableAttrNotFound(Exception): + def __init__(self, table, key_name, key_value, attr_name): + message = "failed to find in table %s a value for %s where %s is %s" % (table, attr_name, key_name, key_value) + super(TableAttrNotFound, self).__init__(message) + self.table = table + self.key_name = key_name + self.key_value = key_value + self.attr_name = attr_name + + class SqlDatabaseReader(object): def __init__(self, inv_provider): @@ -142,6 +152,8 @@ class SqlDatabaseReader(object): rows = self.query("SELECT " + attr_name + " FROM " + table + " WHERE " + key_name + "='" + key_value + "'") if len(rows) > 0: attr_value = rows[0][0] + else: + raise TableAttrNotFound(table, key_name, key_value, attr_name) return attr_value diff --git a/inventory.py b/inventory.py index e9beeb6..c0fc408 100644 --- a/inventory.py +++ b/inventory.py @@ -1,8 +1,25 @@ # encoding: utf-8 import datetime +from Lib import SimpaDbUtil + + +class MachineSpecIdNotFound(Exception): + def __init__(self, machine_name): + message = "failed to find the machine_spec_id for the machine '%s'" % machine_name + super(MachineSpecIdNotFound, self).__init__(message) + self.machine_name = machine_name + + +class PlugTypeNotFound(Exception): + def __init__(self, machine_spec_id, plug_name): + message = "failed to find the plug_type for the machine_spec_id '%s' and plug_name '%s'" % (machine_spec_id, plug_name) + super(PlugTypeNotFound, self).__init__(message) + self.machine_spec_id = machine_spec_id + self.plug_name = plug_name class Inventory(object): + def __init__(self, sql_reader): """ :param SimpaDbUtil.SqlDatabaseReader sql_reader: the inventory database @@ -28,39 +45,68 @@ class Inventory(object): return machine_name def machine_name_to_machine_spec_id(self, machine_name): - # machine_spec_id = None - # try: machine_spec_id = self._sql_reader.get_table_attr('machines', 'name', machine_name, 'machine_spec_id') - # except: - # machine_spec_id = None return machine_spec_id # electricity related methods def machine_spec_id_to_power_consumption(self, machine_spec_id): - power_consumption = self._sql_reader.get_table_attr('machine_spec_to_power_consumption', 'machine_spec_id', machine_spec_id, 'power_consumption') + try: + power_consumption = 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 + # 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 def get_plug_type_attr(self, plug_type, attr_name): + """ + :param str plug_type: eg 'c14' + """ # INSERT INTO `powerplug_type_desc` (`plug_type_id`, `genre`, `max_amps`) VALUES # ('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 read_plug_capacity(self, plug): - plug_capacity = None - machine_spec_id = self.machine_name_to_machine_spec_id(plug.machine.name) + def get_plug_type(self, machine_name, plug_name): + """ + :param str machine_name: eg 'pdu4' + :param str plug_name: eg 'o4' + """ + machine_spec_id = None + try: + machine_spec_id = self.machine_name_to_machine_spec_id(machine_name) + except SimpaDbUtil.TableAttrNotFound as e: # @UnusedVariable + raise MachineSpecIdNotFound(machine_name) if machine_spec_id is not None: # INSERT INTO `powerplug_desc` (`machine_spec_id`, `powerplug_id`, `plug_type`) VALUES # ('atos_mpdu_2901382', 'i', 'iec60309_blue_pne6h_32a_m'), - rows = self._sql_reader.query("SELECT plug_type FROM powerplug_desc WHERE machine_spec_id='%s' AND powerplug_id='%s'" % (machine_spec_id, plug.name)) + rows = self._sql_reader.query("SELECT plug_type FROM powerplug_desc WHERE machine_spec_id='%s' AND powerplug_id='%s'" % (machine_spec_id, plug_name)) if len(rows) > 0: plug_type = rows[0][0] - # 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) + 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) + """ + plug_capacity = None + plug_type = None + try: + plug_type = self.get_plug_type(plug.machine.name, plug.name) + except MachineSpecIdNotFound: + # some machines are not actual machines (eg edf, ups1pdu) + pass + 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) # print("read_plug_capacity : plug capacity for plug.machine.name="+plug.machine.name+" plug="+str(plug)+" : "+ str(plug_capacity)+ "A") return plug_capacity