nodes: 0, module; 1, function_definition; 2, function_name:check_voltage; 3, parameters; 4, block; 5, identifier:grid; 6, identifier:mode; 7, expression_statement; 8, expression_statement; 9, if_statement; 10, if_statement; 11, return_statement; 12, comment:""" Checks for voltage stability issues at all nodes for MV or LV grid
  
      Parameters
      ----------
      grid : GridDing0
          Grid identifier.
      mode : str
          Kind of grid ('MV' or 'LV').
  
      Returns
      -------
      :any:`list` of :any:`GridDing0`
          List of critical nodes, sorted descending by voltage difference.
  
      Notes
      -----
          The examination is done in two steps, according to [#]_ :
          
          1. It is checked #TODO: what?
          
          2. #TODO: what's next?
          
      References
      ----------
      .. [#] dena VNS
      """; 13, assignment; 14, comparison_operator:mode == 'MV'; 15, comment:# load max. voltage difference for load and feedin case; 16, block; 17, elif_clause; 18, identifier:crit_nodes; 19, block; 20, list_comprehension; 21, identifier:crit_nodes; 22, dictionary; 23, identifier:mode; 24, string; 25, expression_statement; 26, expression_statement; 27, comment:# check nodes' voltages; 28, expression_statement; 29, for_statement; 30, comparison_operator:mode == 'LV'; 31, block; 32, expression_statement; 33, subscript; 34, for_in_clause; 35, string_content:MV; 36, assignment; 37, assignment; 38, assignment; 39, identifier:node; 40, call; 41, block; 42, identifier:mode; 43, string; 44, raise_statement; 45, call; 46, identifier:_; 47, string; 48, identifier:_; 49, call; 50, identifier:mv_max_v_level_lc_diff_normal; 51, call; 52, identifier:mv_max_v_level_fc_diff_normal; 53, call; 54, identifier:voltage_station; 55, attribute; 56, attribute; 57, argument_list; 58, try_statement; 59, string_content:LV; 60, identifier:NotImplementedError; 61, attribute; 62, argument_list; 63, string_content:node; 64, identifier:sorted; 65, argument_list; 66, identifier:float; 67, argument_list; 68, identifier:float; 69, argument_list; 70, attribute; 71, identifier:voltage_res; 72, identifier:grid; 73, identifier:graph_nodes_sorted; 74, comment:# compare node's voltage with max. allowed voltage difference for load and feedin case; 75, block; 76, except_clause; 77, identifier:logger; 78, identifier:info; 79, call; 80, call; 81, keyword_argument; 82, keyword_argument; 83, call; 84, call; 85, identifier:grid; 86, identifier:_station; 87, if_statement; 88, block; 89, attribute; 90, argument_list; 91, attribute; 92, argument_list; 93, identifier:key; 94, lambda; 95, identifier:reverse; 96, True; 97, attribute; 98, argument_list; 99, attribute; 100, argument_list; 101, boolean_operator; 102, block; 103, pass_statement; 104, string; 105, identifier:format; 106, call; 107, identifier:crit_nodes; 108, identifier:values; 109, lambda_parameters; 110, subscript; 111, identifier:cfg_ding0; 112, identifier:get; 113, string; 114, string; 115, identifier:cfg_ding0; 116, identifier:get; 117, string; 118, string; 119, parenthesized_expression; 120, line_continuation:\; 121, parenthesized_expression; 122, expression_statement; 123, string_content:==> {} nodes have voltage issues.; 124, identifier:len; 125, argument_list; 126, identifier:_; 127, identifier:_; 128, string; 129, string_content:mv_routing_tech_constraints; 130, string_content:mv_max_v_level_lc_diff_normal; 131, string_content:mv_routing_tech_constraints; 132, string_content:mv_max_v_level_fc_diff_normal; 133, comparison_operator:abs(voltage_station[0] - node.voltage_res[0]) > mv_max_v_level_lc_diff_normal; 134, comparison_operator:abs(voltage_station[1] - node.voltage_res[1]) > mv_max_v_level_fc_diff_normal; 135, assignment; 136, identifier:crit_nodes; 137, string_content:v_diff; 138, call; 139, identifier:mv_max_v_level_lc_diff_normal; 140, call; 141, identifier:mv_max_v_level_fc_diff_normal; 142, subscript; 143, dictionary; 144, identifier:abs; 145, argument_list; 146, identifier:abs; 147, argument_list; 148, identifier:crit_nodes; 149, identifier:node; 150, pair; 151, pair; 152, binary_operator:voltage_station[0] - node.voltage_res[0]; 153, binary_operator:voltage_station[1] - node.voltage_res[1]; 154, string; 155, identifier:node; 156, string; 157, call; 158, subscript; 159, subscript; 160, subscript; 161, subscript; 162, string_content:node; 163, string_content:v_diff; 164, identifier:max; 165, argument_list; 166, identifier:voltage_station; 167, integer:0; 168, attribute; 169, integer:0; 170, identifier:voltage_station; 171, integer:1; 172, attribute; 173, integer:1; 174, list_comprehension; 175, identifier:node; 176, identifier:voltage_res; 177, identifier:node; 178, identifier:voltage_res; 179, call; 180, for_in_clause; 181, identifier:abs; 182, argument_list; 183, pattern_list; 184, call; 185, binary_operator:v2-v1; 186, identifier:v1; 187, identifier:v2; 188, identifier:zip; 189, argument_list; 190, identifier:v2; 191, identifier:v1; 192, attribute; 193, identifier:voltage_station; 194, identifier:node; 195, identifier:voltage_res
code: def check_voltage(grid, mode):
      """ Checks for voltage stability issues at all nodes for MV or LV grid
  
      Parameters
      ----------
      grid : GridDing0
          Grid identifier.
      mode : str
          Kind of grid ('MV' or 'LV').
  
      Returns
      -------
      :any:`list` of :any:`GridDing0`
          List of critical nodes, sorted descending by voltage difference.
  
      Notes
      -----
          The examination is done in two steps, according to [#]_ :
          
          1. It is checked #TODO: what?
          
          2. #TODO: what's next?
          
      References
      ----------
      .. [#] dena VNS
      """
  
      crit_nodes = {}
  
      if mode == 'MV':
          # load max. voltage difference for load and feedin case
          mv_max_v_level_lc_diff_normal = float(cfg_ding0.get('mv_routing_tech_constraints',
                                                              'mv_max_v_level_lc_diff_normal'))
          mv_max_v_level_fc_diff_normal = float(cfg_ding0.get('mv_routing_tech_constraints',
                                                              'mv_max_v_level_fc_diff_normal'))
  
          # check nodes' voltages
          voltage_station = grid._station.voltage_res
          for node in grid.graph_nodes_sorted():
              try:
                  # compare node's voltage with max. allowed voltage difference for load and feedin case
                  if (abs(voltage_station[0] - node.voltage_res[0]) > mv_max_v_level_lc_diff_normal) or\
                     (abs(voltage_station[1] - node.voltage_res[1]) > mv_max_v_level_fc_diff_normal):
  
                      crit_nodes[node] = {'node': node,
                                          'v_diff': max([abs(v2-v1) for v1, v2 in zip(node.voltage_res, voltage_station)])}
              except:
                  pass
  
      elif mode == 'LV':
          raise NotImplementedError
  
      if crit_nodes:
          logger.info('==> {} nodes have voltage issues.'.format(len(crit_nodes)))
  
      return [_['node'] for _ in sorted(crit_nodes.values(), key=lambda _: _['v_diff'], reverse=True)]