1#!/usr/bin/env python3 2# 3# Copyright 2020 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the 'License'); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an 'AS IS' BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import copy 18 19DEFAULT_MONSOON_CONFIG_DICT = { 20 'enabled': 1, 21 'type': 'monsooncollector', 22 'monsoon_reset': 0, 23 # maximum monsoon sample rate that works best for both lvpm and hvpm 24 'sampling_rate': 1000, 25} 26 27 28class _BitsMonsoonConfig(object): 29 """Helper object to construct a bits_service config from a monsoon config as 30 defined for the bits controller config and required additional resources, 31 such as paths to executables. 32 33 The format for the bits_service's monsoon configuration is explained at: 34 http://go/pixel-bits/user-guide/service/collectors/monsoon 35 36 Attributes: 37 config_dic: A bits_service's monsoon configuration as a python 38 dictionary. 39 """ 40 41 def __init__(self, monsoon_config, lvpm_monsoon_bin=None, 42 hvpm_monsoon_bin=None): 43 """Constructs _BitsServiceMonsoonConfig. 44 45 Args: 46 monsoon_config: The monsoon config as defined in the 47 ACTS Bits controller config. Expected format is: 48 { 'serial_num': <serial number:int>, 49 'monsoon_voltage': <voltage:double> } 50 lvpm_monsoon_bin: Binary file to interact with low voltage monsoons. 51 Needed if the monsoon is a lvpm monsoon (serial number lower 52 than 20000). 53 hvpm_monsoon_bin: Binary file to interact with high voltage 54 monsoons. Needed if the monsoon is a hvpm monsoon (serial number 55 greater than 20000). 56 """ 57 if 'serial_num' not in monsoon_config: 58 raise ValueError( 59 'Monsoon serial_num can not be undefined. Received ' 60 'config was: %s' % monsoon_config) 61 if 'monsoon_voltage' not in monsoon_config: 62 raise ValueError('Monsoon voltage can not be undefined. Received ' 63 'config was: %s' % monsoon_config) 64 65 self.serial_num = int(monsoon_config['serial_num']) 66 self.monsoon_voltage = float(monsoon_config['monsoon_voltage']) 67 68 self.config_dic = copy.deepcopy(DEFAULT_MONSOON_CONFIG_DICT) 69 if float(self.serial_num) >= 20000: 70 self.config_dic['hv_monsoon'] = 1 71 if hvpm_monsoon_bin is None: 72 raise ValueError('hvpm_monsoon binary is needed but was None. ' 73 'Received config was: %s' % monsoon_config) 74 self.monsoon_binary = hvpm_monsoon_bin 75 else: 76 self.config_dic['hv_monsoon'] = 0 77 if lvpm_monsoon_bin is None: 78 raise ValueError('lvpm_monsoon binary is needed but was None. ' 79 'Received config was: %s' % monsoon_config) 80 self.monsoon_binary = lvpm_monsoon_bin 81 82 self.config_dic['monsoon_binary_path'] = self.monsoon_binary 83 self.config_dic['monsoon_voltage'] = self.monsoon_voltage 84 self.config_dic['serial_num'] = self.serial_num 85 86 87DEFAULT_KIBBLES_BOARD_CONFIG = { 88 'enabled': 1, 89 'type': 'kibblecollector', 90 'attached_kibbles': {} 91} 92 93DEFAULT_KIBBLE_CONFIG = { 94 'ultra_channels_current_hz': 976.5625, 95 'ultra_channels_voltage_hz': 976.5625, 96 'high_channels_current_hz': 976.5625, 97 'high_channels_voltage_hz': 976.5625 98} 99 100 101class _BitsKibblesConfig(object): 102 def __init__(self, kibbles_config, kibble_bin, kibble_board_file): 103 """Constructs _BitsKibblesConfig. 104 105 Args: 106 kibbles_config: A list of compacted kibble boards descriptions. 107 Expected format is: 108 [{ 109 'board': 'BoardName1', 110 'connector': 'A', 111 'serial': 'serial_1' 112 }, 113 { 114 'board': 'BoardName2', 115 'connector': 'D', 116 'serial': 'serial_2' 117 }] 118 More details can be found at go/acts-bits. 119 kibble_bin: Binary file to interact with kibbles. 120 kibble_board_file: File describing the distribution of rails on a 121 kibble. go/kibble#setting-up-bits-board-files 122 """ 123 124 if not isinstance(kibbles_config, list): 125 raise ValueError( 126 'kibbles_config must be a list. Got %s.' % kibbles_config) 127 128 if kibble_bin is None: 129 raise ValueError('Kibbles were present in the config but no ' 130 'kibble_bin was provided') 131 if kibble_board_file is None: 132 raise ValueError('Kibbles were present in the config but no ' 133 'kibble_board_file was provided') 134 135 self.boards_configs = {} 136 137 for kibble in kibbles_config: 138 if 'board' not in kibble: 139 raise ValueError('An individual kibble config must have a ' 140 'board') 141 if 'connector' not in kibble: 142 raise ValueError('An individual kibble config must have a ' 143 'connector') 144 if 'serial' not in kibble: 145 raise ValueError('An individual kibble config must have a ' 146 'serial') 147 if 'subkibble_params' in kibble: 148 user_defined_kibble_config = kibble['subkibble_params'] 149 kibble_config = copy.deepcopy(user_defined_kibble_config) 150 else: 151 kibble_config = copy.deepcopy(DEFAULT_KIBBLE_CONFIG) 152 board = kibble['board'] 153 connector = kibble['connector'] 154 serial = kibble['serial'] 155 if board not in self.boards_configs: 156 self.boards_configs[board] = copy.deepcopy( 157 DEFAULT_KIBBLES_BOARD_CONFIG) 158 self.boards_configs[board][ 159 'board_file'] = kibble_board_file 160 self.boards_configs[board]['kibble_py'] = kibble_bin 161 kibble_config['connector'] = connector 162 self.boards_configs[board]['attached_kibbles'][ 163 serial] = kibble_config 164 165 166DEFAULT_SERVICE_CONFIG_DICT = { 167 'devices': { 168 'default_device': { 169 'enabled': 1, 170 'collectors': {} 171 } 172 } 173} 174 175 176class BitsServiceConfig(object): 177 """Helper object to construct a bits_service config from a bits controller 178 config and required additional resources, such as paths to executables. 179 180 The format for bits_service's configuration is explained in: 181 go/pixel-bits/user-guide/service/configuration.md 182 183 Attributes: 184 config_dic: A bits_service configuration as a python dictionary. 185 """ 186 187 def __init__(self, controller_config, lvpm_monsoon_bin=None, 188 hvpm_monsoon_bin=None, kibble_bin=None, 189 kibble_board_file=None, virtual_metrics_file=None): 190 """Creates a BitsServiceConfig. 191 192 Args: 193 controller_config: The config as defined in the ACTS BiTS 194 controller config. Expected format is: 195 { 196 // optional 197 'Monsoon': { 198 'serial_num': <serial number:int>, 199 'monsoon_voltage': <voltage:double> 200 } 201 // optional 202 'Kibble': [ 203 { 204 'board': 'BoardName1', 205 'connector': 'A', 206 'serial': 'serial_1' 207 }, 208 { 209 'board': 'BoardName2', 210 'connector': 'D', 211 'serial': 'serial_2' 212 } 213 ] 214 } 215 lvpm_monsoon_bin: Binary file to interact with low voltage monsoons. 216 Needed if the monsoon is a lvpm monsoon (serial number lower 217 than 20000). 218 hvpm_monsoon_bin: Binary file to interact with high voltage 219 monsoons. Needed if the monsoon is a hvpm monsoon (serial number 220 greater than 20000). 221 kibble_bin: Binary file to interact with kibbles. 222 kibble_board_file: File describing the distribution of rails on a 223 kibble. go/kibble#setting-up-bits-board-files 224 virtual_metrics_file: A list of virtual metrics files to add 225 data aggregates on top of regular channel aggregates. 226 go/pixel-bits/user-guide/virtual-metrics 227 """ 228 self.config_dic = copy.deepcopy(DEFAULT_SERVICE_CONFIG_DICT) 229 self.has_monsoon = False 230 self.has_kibbles = False 231 self.has_virtual_metrics_file = False 232 self.monsoon_config = None 233 self.kibbles_config = None 234 if 'Monsoon' in controller_config: 235 self.has_monsoon = True 236 self.monsoon_config = _BitsMonsoonConfig( 237 controller_config['Monsoon'], 238 lvpm_monsoon_bin, 239 hvpm_monsoon_bin) 240 self.config_dic['devices']['default_device']['collectors'][ 241 'Monsoon'] = self.monsoon_config.config_dic 242 if 'Kibbles' in controller_config: 243 self.has_kibbles = True 244 self.kibbles_config = _BitsKibblesConfig( 245 controller_config['Kibbles'], 246 kibble_bin, kibble_board_file) 247 self.config_dic['devices']['default_device']['collectors'].update( 248 self.kibbles_config.boards_configs) 249 if virtual_metrics_file is not None: 250 self.config_dic['devices']['default_device'][ 251 'vm_files'] = [virtual_metrics_file] 252 self.has_virtual_metrics_file = True 253