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 = monsoon_config['serial_num'] 66 self.monsoon_voltage = 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 148 board = kibble['board'] 149 connector = kibble['connector'] 150 serial = kibble['serial'] 151 if board not in self.boards_configs: 152 self.boards_configs[board] = copy.deepcopy( 153 DEFAULT_KIBBLES_BOARD_CONFIG) 154 self.boards_configs[board][ 155 'board_file'] = kibble_board_file 156 self.boards_configs[board]['kibble_py'] = kibble_bin 157 kibble_config = copy.deepcopy(DEFAULT_KIBBLE_CONFIG) 158 kibble_config['connector'] = connector 159 self.boards_configs[board]['attached_kibbles'][ 160 serial] = kibble_config 161 162 163DEFAULT_SERVICE_CONFIG_DICT = { 164 'devices': { 165 'default_device': { 166 'enabled': 1, 167 'collectors': {} 168 } 169 } 170} 171 172 173class BitsServiceConfig(object): 174 """Helper object to construct a bits_service config from a bits controller 175 config and required additional resources, such as paths to executables. 176 177 The format for bits_service's configuration is explained in: 178 go/pixel-bits/user-guide/service/configuration.md 179 180 Attributes: 181 config_dic: A bits_service configuration as a python dictionary. 182 """ 183 184 def __init__(self, controller_config, lvpm_monsoon_bin=None, 185 hvpm_monsoon_bin=None, kibble_bin=None, 186 kibble_board_file=None, virtual_metrics_file=None): 187 """Creates a BitsServiceConfig. 188 189 Args: 190 controller_config: The config as defined in the ACTS BiTS 191 controller config. Expected format is: 192 { 193 // optional 194 'Monsoon': { 195 'serial_num': <serial number:int>, 196 'monsoon_voltage': <voltage:double> 197 } 198 // optional 199 'Kibble': [ 200 { 201 'board': 'BoardName1', 202 'connector': 'A', 203 'serial': 'serial_1' 204 }, 205 { 206 'board': 'BoardName2', 207 'connector': 'D', 208 'serial': 'serial_2' 209 } 210 ] 211 } 212 lvpm_monsoon_bin: Binary file to interact with low voltage monsoons. 213 Needed if the monsoon is a lvpm monsoon (serial number lower 214 than 20000). 215 hvpm_monsoon_bin: Binary file to interact with high voltage 216 monsoons. Needed if the monsoon is a hvpm monsoon (serial number 217 greater than 20000). 218 kibble_bin: Binary file to interact with kibbles. 219 kibble_board_file: File describing the distribution of rails on a 220 kibble. go/kibble#setting-up-bits-board-files 221 virtual_metrics_file: A list of virtual metrics files to add 222 data aggregates on top of regular channel aggregates. 223 go/pixel-bits/user-guide/virtual-metrics 224 """ 225 self.config_dic = copy.deepcopy(DEFAULT_SERVICE_CONFIG_DICT) 226 self.has_monsoon = False 227 self.has_kibbles = False 228 self.has_virtual_metrics_file = False 229 self.monsoon_config = None 230 self.kibbles_config = None 231 if 'Monsoon' in controller_config: 232 self.has_monsoon = True 233 self.monsoon_config = _BitsMonsoonConfig( 234 controller_config['Monsoon'], 235 lvpm_monsoon_bin, 236 hvpm_monsoon_bin) 237 self.config_dic['devices']['default_device']['collectors'][ 238 'Monsoon'] = self.monsoon_config.config_dic 239 if 'Kibbles' in controller_config: 240 self.has_kibbles = True 241 self.kibbles_config = _BitsKibblesConfig( 242 controller_config['Kibbles'], 243 kibble_bin, kibble_board_file) 244 self.config_dic['devices']['default_device']['collectors'].update( 245 self.kibbles_config.boards_configs) 246 if virtual_metrics_file is not None: 247 self.config_dic['devices']['default_device'][ 248 'vm_files'] = [virtual_metrics_file] 249 self.has_virtual_metrics_file = True 250