def on_power_button_on(self, event, *args, **kwargs): """React to power button event by notifying engine of state changes associated with it""" asset_event = event.get_next_power_event() load_upd = {} extra_draw = 0.0 online_psus = [] asset_event.load.new = asset_event.calculate_load( self.state, self.state.input_voltage) # for each psu, check if for key in self._psu_sm: psu_sm = self._psu_sm[key] load_upd[key] = EventDataPair(psu_sm.load, psu_sm.load) if not psu_sm.status: extra_draw += psu_sm.draw_percentage else: load_upd[key].new = ( load_upd[key].new + asset_event.load.new * psu_sm.draw_percentage) online_psus.append(key) extra_load = asset_event.load.new * extra_draw / len(online_psus) for key in online_psus: load_upd[key].new = load_upd[key].new + extra_load asset_event.streamed_load_updates = load_upd return asset_event
def on_power_button_off(self, event, *args, **kwargs): """React to server shut down by setting up upstream load for server PSUs""" asset_event = event.get_next_power_event() load_upd = {} asset_event.load.new = asset_event.calculate_load( self.state, self.state.input_voltage) for key in self._psu_sm: psu_sm = self._psu_sm[key] load_upd[key] = EventDataPair(psu_sm.load, psu_sm.load) if not psu_sm.status or math.isclose(psu_sm.input_voltage, 0.0): continue load_upd[key].new = psu_sm.power_usage asset_event.streamed_load_updates = load_upd return asset_event
def on_input_voltage_down(self, event, *args, **kwargs): asset_event = event.get_next_power_event(self) assert event.source_key in self._psu_sm # store state info of the PSU causing havoc, keep track # of alternative power sources e_src_psu = self._psu_sm[event.source_key] e_src_psu_offline = math.isclose(event.in_volt.new, 0.0) alt_power_present = False if not math.isclose(self.state.load * e_src_psu.draw_percentage, e_src_psu.load): source_psu_own_load = asset_event.calculate_load( e_src_psu, event.in_volt.old) else: source_psu_own_load = 0 # keep track of load updates for multi-psu servers load_upd = {} # initialize load for PSUs (as unchanged) for key in self._psu_sm: load_upd[key] = EventDataPair(self._psu_sm[key].load, self._psu_sm[key].load) load_upd[e_src_psu.key].new = ( asset_event.calculate_load(self.state, event.in_volt.new) * e_src_psu.draw_percentage) # check alternative power sources # and leave this server online if present for psu_key in self._psu_sm: psu_sm = self._psu_sm[psu_key] # skip over source event psu or offline psus if psu_key == e_src_psu.key or not psu_sm.status: continue alt_power_present = True # no load redistribution happens if source is still online if not e_src_psu_offline: continue # distribute load to another PSU load_upd[psu_key].new = (load_upd[psu_key].new - load_upd[e_src_psu.key].difference - source_psu_own_load) # finalize asset state changes based off PSU and in-volt status if not alt_power_present and e_src_psu_offline: # state needs to change when all power sources are offline asset_event.state.new = self.power_off() # update server load if all PSUs are off or # if in voltage simply dropped (but not to zero) if not alt_power_present or not e_src_psu_offline: asset_event.calc_load_from_volt() self._update_load(self.state.load + load_upd[e_src_psu.key].difference) asset_event.streamed_load_updates = load_upd return asset_event
def on_input_voltage_up(self, event, *args, **kwargs): asset_event = event.get_next_power_event(self) assert event.source_key in self._psu_sm e_src_psu = self._psu_sm[event.source_key] # keep track of load updates for multi-psu servers load_upd = {} extra_draw = 0.0 should_change_load = True should_power_up = (not self.state.status or not self.state.vm_is_active()) and not math.isclose( event.in_volt.new, 0.0) new_asset_load = asset_event.calculate_load(self.state, event.in_volt.new) old_asset_load = asset_event.calculate_load(self.state, event.in_volt.old) # initialize load for PSUs # and process alternative power sources (PSUs) for key in self._psu_sm: psu_sm = self._psu_sm[key] load_upd[key] = EventDataPair(0.0, 0.0) if psu_sm.key == event.source_key: continue # if alternative power source is off, grab extra load from it if not psu_sm.status: extra_draw += psu_sm.draw_percentage # if alternative power source is currently having extra load # that the volt event source asset is supposed to be drawing # then redistribute it back so that load is equal among all psus elif math.isclose(event.in_volt.old, 0.0) and self._psu_drawing_extra(psu_sm): # asset load should not change (we are just redistributing same load) load_upd[key].old = psu_sm.load load_upd[key].new = ( psu_sm.load - new_asset_load * e_src_psu.draw_percentage) should_change_load = False # add load to a psu due to server powering up elif should_power_up: load_upd[ psu_sm.key].new = new_asset_load * psu_sm.draw_percentage # set load for the PSU voltage event is associated with src_psu_draw = e_src_psu.draw_percentage + extra_draw load_upd[e_src_psu.key].old = old_asset_load * src_psu_draw load_upd[e_src_psu.key].new = new_asset_load * src_psu_draw # power up if server is offline & boot-on-power BIOS option is on if should_power_up and self.state.power_on_ac_restored: asset_event.state.new = self.power_up() self._update_load(self.state.power_consumption / event.in_volt.new) # update load if no state changes elif not should_power_up and should_change_load: asset_event.calc_load_from_volt() self._update_load(self.state.load + load_upd[e_src_psu.key].difference) elif not self.state.status and not self.state.power_on_ac_restored: load_upd = {} asset_event.streamed_load_updates = load_upd return asset_event