def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py if len(lastPowerDown) == 0: lastPowerDown.append(-1000) MIN_ENERGY_FOR_BATTERY = MINIMAL_BATTERY_POWER_FOR_LOAD_1 if msg.grid_status == False: lastPowerDown[0] = msg.id else: if msg.id - lastPowerDown[0] < PERIOD_WITHOUT_POWER_DOWN: MIN_ENERGY_FOR_BATTERY = 0.11 if len(minBuyingCosts) == 0: minBuyingCosts.append(msg.buying_price) maxBuyingCosts.append(msg.buying_price) sellingCosts.append(msg.selling_price) else: if minBuyingCosts[0] > msg.buying_price: minBuyingCosts[0] = msg.buying_price if maxBuyingCosts[0] < msg.buying_price: maxBuyingCosts[0] = msg.buying_price if sellingCosts[0] < msg.selling_price: sellingCosts[0] = msg.selling_price # Save received status from framework saveReceivedStatus(msg, listOfReceivedStatuses) # set default output message witch should be changed batteryUsing = 0.0 newOutput = ResultsMessage(msg, True, True, True, batteryUsing, PVMode.ON) shutdownLoadIfPowerIsExpensive(listOfReceivedStatuses[0], newOutput) defaultOutputStatus = ResultsMessage( msg, True, True, True, 0.0, PVMode.ON) if len(listOfSentStatuses) == 0 else listOfSentStatuses[0] # Prevent battery overload if msg.bessOverload: preventBessOverload(listOfReceivedStatuses[0], defaultOutputStatus, newOutput, minBuyingCosts[0], maxBuyingCosts[0], MIN_ENERGY_FOR_BATTERY) else: handleRegularScenarios(listOfReceivedStatuses[0], defaultOutputStatus, newOutput, minBuyingCosts[0], maxBuyingCosts[0], MIN_ENERGY_FOR_BATTERY) saveSentStatus(newOutput, listOfSentStatuses) if msg.id - lastPowerDown[ 0] > PERIOD_WITHOUT_POWER_DOWN and msg.bessSOC * 10.0 < MINIMAL_BATTERY_POWER_FOR_LOAD_1: newOutput.power_reference = -6.0 return newOutput
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py global cheapPrice global currentIteration global maxIteration if not msg.grid_status: currentIteration = 0 currentIteration += 1 if msg.buying_price < cheapPrice: cheapPrice = msg.buying_price if msg.grid_status == True: return gridOn(msg) else: return gridOff(msg) # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON)
def stedi(msg): load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON extra_production = msg.solar_production - msg.current_load if msg.grid_status: # radi elektrovojvodina if msg.buying_price / 60.0 > 0.1: # više se isplati gasiti load3 nego puniti iz elektrovojvodine load_three = False power_reference = -0.1 else: # ne radi elektrovojvodina if extra_production <= 0: # nema dovoljno sunca if msg.current_load * 0.2 > msg.solar_production: # čak i sa samo load1 trošimo previše pa isključi sve load_one = False load_two = False load_three = False elif msg.current_load * 0.5 > msg.solar_production: # isključenjem load2 trošimo previše load_two = False load_three = False elif msg.current_load * 0.7 < msg.solar_production: # dovoljno je isključiti samo load3 load_three = False else: # dovoljno je isključiti samo load2 load_two = False result = ResultsMessage( data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode, ) return result
def get_result(msg): return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py (power_reference, pv_mode) = ChargingHandler(msg) (load_one, load_two, load_three, power_reference) = BlackoutHandler(msg, power_reference) return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def gridOn(msg: DataMessage) -> ResultsMessage: if currentIteration < maxIteration: if msg.bessSOC < 1 and msg.buying_price <= cheapPrice: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=-6.0, pv_mode=PVMode.ON) elif msg.buying_price > cheapPrice: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=2.0, pv_mode=PVMode.ON) else: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON) else: if msg.bessSOC < 1 and msg.buying_price <= cheapPrice: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=-6.0, pv_mode=PVMode.ON) elif msg.bessSOC > 0.6 and msg.buying_price > cheapPrice: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=2.0, pv_mode=PVMode.ON) elif msg.bessSOC < 0.6 and msg.buying_price > cheapPrice: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=False, power_reference=0.0, pv_mode=PVMode.ON) else: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py if msg.current_load > 2.5: #ako krene da trosi vise if msg.solar_production - msg.current_load > 0 or msg.buying_price < 5: #proveravamo da li #panel proizvodi vise nego sto trosimo ili je jeftina struja #moze da bude ukljucen bojler... load3 = True else: #u drugom slucaju nikako load3 = False else: #ako ne divlja struja okej je da bude upaljen bojler i ako je skupa struja load3 = True #ako je skupa struja if msg.current_load > 7.0: # proverimo da li divlja ###### ovo sam promenio bilo je 7 if msg.solar_production - msg.current_load > 0: #ako divlja proveravamo da li proizvodimo #vise nego sto trosimo, okej je da bude upaljen u tom slucaju load2 = True else: #gasimo i to ako se ovo gore ne desi load2 = False else: #ako je jeftina struja moze da bude ukljucen load2 = True pr = calculatePowerReference(msg) if (7140 < msg.id <= 7200 and msg.bessSOC > 0.05) and msg.grid_status: loadSum = 0.2 if load2: loadSum += 0.5 if load3: loadSum += 0.3 pr = loadSum * msg.current_load if pr > 6.0: pr = 1.0 pv = calculatePV(msg) return ResultsMessage(data_msg=msg, load_one=True, load_two=load2, load_three=load3, power_reference=pr, pv_mode=pv)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON # predicted_consumtrion is supposed to be predicted by Tensorflow model # but we could not import trained model into the typhoon framework predicted_consumption = 1.2 max_charging = 5.0 # if msg.grid_status: if msg.bessSOC < 1 and msg.buying_price == msg.selling_price and msg.id < 7000: power_reference = -max_charging msg.mainGridPower = msg.current_load + max_charging - msg.solar_production elif (msg.bessSOC * 20) > (predicted_consumption * 1.5) and msg.buying_price == 8.0: power_reference = max_charging msg.mainGridPower = msg.current_load - max_charging - msg.solar_production if msg.solar_production > msg.current_load and msg.buying_price == 3.0: msg.mainGridPower = msg.current_load - msg.solar_production elif msg.solar_production > msg.current_load: power_reference = msg.current_load - msg.solar_production else: pv_mode = PVMode.OFF if msg.current_load < msg.solar_production and msg.bessSOC == 1: power_reference = max_charging if msg.current_load > (max_charging + msg.solar_production): load_three = False if msg.current_load > (max_charging + msg.solar_production): load_two = False return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def potrosi(msg): load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON extra_production = msg.solar_production - msg.current_load if msg.grid_status: # radi elektrovojvodina if extra_production < 0: # pravim manje energije od max load if msg.solar_production + 6.0 < msg.current_load: # panel i baterija prave manje energije od max load power_reference = 6.0 if msg.buying_price / 60.0 >= 0.1: # više se isplati gasiti load3 nego kupovati load_three = False else: # panel i baterija mogu da prave makar max load if extra_production < -6.0: power_reference = 6.0 else: power_reference = -extra_production else: # pravim barem energije od max load power_reference = 0.1 else: # ne radi elektrovojvodina if extra_production >= 0: # pravim iz panela barem max load pv_mode = PVMode.OFF if msg.current_load * 0.7 >= 6.0: # isklučenje load3 nije dovoljno load_two = False else: # isključenje load3 je dovoljno load_three = False else: # pravim iz panela manje od max load if msg.solar_production + 6.0 <= msg.current_load: # panel i baterija ne prave dovoljno current_load = msg.current_load * 0.7 if msg.solar_production + 6.0 < current_load: # panel i baterija prave manje od load1 + load2 load_two = False # tloken else: # panel i baterija prave barem load1 + load2 load_three = False result = ResultsMessage( data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode, ) return result
def grid_off(msg: DataMessage) -> ResultsMessage: load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON if msg.bessSOC > 0.8 or msg.current_load + BATTERY_MAX_POWER < msg.solar_production: pv_mode = PVMode.OFF if msg.current_load < BATTERY_MAX_POWER: power_reference = msg.current_load elif msg.current_load * 0.6 < BATTERY_MAX_POWER: power_reference = msg.current_load * 0.6 load_three = False elif msg.current_load * 0.2 < BATTERY_MAX_POWER: power_reference = msg.current_load * 0.2 load_three = False load_two = False else: if msg.current_load <= msg.solar_production: power_reference = 0.0 elif msg.current_load <= msg.solar_production + BATTERY_MAX_POWER: if msg.current_load - msg.solar_production > BATTERY_MAX_POWER: load_three = False power_reference = msg.current_load * 0.6 - msg.solar_production else: power_reference = msg.current_load - msg.solar_production else: if msg.current_load * 0.6 <= msg.solar_production + BATTERY_MAX_POWER: load_three = False power_reference = msg.current_load * 0.6 - msg.solar_production elif msg.current_load * 0.2 <= msg.solar_production + BATTERY_MAX_POWER: load_three = False load_two = False power_reference = msg.current_load * 0.2 - msg.solar_production return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON # if msg.grid_status: # if msg.bessSOC != 1 and msg.buying_price == msg.selling_price \ # and msg.current_load <8: # if msg.bessSOC > 0.45: # power_reference = -5.0 # elif msg.current_load > 8: # power_reference = msg.current_load # # else: # if msg.bessSOC == 1 and msg.solar_production > 0: # if msg.solar_production < msg.current_load: # power_reference = msg.current_load # load_three = False # pv_mode = PVMode.OFF # else: # power_reference = msg.current_load # elif msg.bessSOC != 1: # load_three = False # pv_mode = PVMode.ON # # elif msg.selling_price == msg.buying_price and msg.solar_production == 0: # power_reference = msg.current_load # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def grid_on(msg: DataMessage) -> ResultsMessage: pwr_reference = 0.0 load_three = True if msg.buying_price == 8 and msg.current_load > 6.5: load_three = False can_charge = msg.buying_price == 3 or ( msg.selling_price == 0 and msg.current_load < msg.solar_production) if can_charge and msg.bessSOC < 1: pwr_reference = -2 * BATTERY_MAX_POWER / 3 # punjenje elif msg.bessSOC < 0.25: pwr_reference = -0.5 # puni svakako ako je ispod 0.25 elif msg.bessSOC > 0.27 and msg.selling_price == 3 and msg.buying_price == 8: pwr_reference = 2 * BATTERY_MAX_POWER / 3 # praznjenje return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=load_three, power_reference=pwr_reference, pv_mode=PVMode.ON)
def __init__(self): self.states = [] import itertools as it my_dict = {'1_loadOne': [True], '2_loadTwo': [True, False], '3_loadThree': [True, False], '4_powerRef': [-5.0, -2.5, 0.0, 2.5, 5.0], '5_pvmode': [PVMode.OFF, PVMode.ON]} combinations = it.product(*(my_dict[name] for name in my_dict.keys())) combs = list(combinations) self.actions = [] self.states = [] for comb in combs: self.actions.append(ResultsMessage(None, *comb)) with open('data/profiles.json', 'r') as f, open('data/physics_init.json') as f2: physics = json.loads(f2.read()) state_id = 0 for d in json.loads(f.read()): self.states.append(DataMessage(id=state_id, bessOverload=physics['bessOverload'], bessPower=physics['bessPower'], bessSOC=physics['bessSOC'], mainGridPower=physics['mainGridPower'], grid_status=d['gridStatus'], buying_price=d['buyingPrice'], selling_price=d['sellingPrice'], solar_production=d['solarProduction'], current_max_load=d['currentLoad'])) state_id += 1 self.current_id = 0 self.current = [] self.action_space = spaces.Discrete(len(self.actions)) self.observation_space = spaces.Discrete(7200 * len(self.actions))
def gridOff(msg: DataMessage) -> ResultsMessage: if msg.current_load <= msg.solar_production: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=0.0, pv_mode=PVMode.ON) elif msg.current_load <= msg.solar_production + 6: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=True, power_reference=msg.current_load - msg.solar_production, pv_mode=PVMode.ON) elif msg.current_load - 0.3*msg.current_load <= msg.solar_production + 6: return ResultsMessage(data_msg=msg, load_one=True, load_two=True, load_three=False, power_reference=msg.current_load - msg.solar_production, pv_mode=PVMode.ON) elif msg.current_load - 0.5*msg.current_load <= msg.solar_production + 6: return ResultsMessage(data_msg=msg, load_one=True, load_two=False, load_three=True, power_reference=6.0, pv_mode=PVMode.ON) elif msg.current_load - 0.5*msg.current_load - 0.3*msg.current_load <= msg.solar_production + 6: return ResultsMessage(data_msg=msg, load_one=True, load_two=False, load_three=False, power_reference=6.0, pv_mode=PVMode.ON) else: return ResultsMessage(data_msg=msg, load_one=False, load_two=True, load_three=True, power_reference=6.0, pv_mode=PVMode.ON)
def worker(msg: DataMessage) -> ResultsMessage: load_one_my=True load_two_my=True load_three_my=True power_reference_my=0.0 pv_mode_my=PVMode.ON how_much_i_must_use=msg.current_load- msg.solar_production how_much_energy_battery_has=600*msg.bessSOC if msg.grid_status: if msg.buying_price == 3: if how_much_energy_battery_has < 600: if how_much_energy_battery_has < 300: power_reference_my = - how_much_i_must_use * 4 else: power_reference_my = - how_much_i_must_use * 2 else: power_reference_my = - how_much_i_must_use elif msg.buying_price == 8 and msg.current_load > 5.0: #5 energy_of_load3=how_much_i_must_use*0.3 load_three_my=False power_reference_my=msg.current_load-how_much_i_must_use*0.3 else: if_buttery_stil_has_energy=how_much_energy_battery_has-how_much_i_must_use if if_buttery_stil_has_energy < 450: power_reference_my=how_much_i_must_use-200 elif if_buttery_stil_has_energy < 300: power_reference_my=how_much_i_must_use-300 elif if_buttery_stil_has_energy < 150: power_reference_my=how_much_i_must_use-400 if if_buttery_stil_has_energy>0: power_reference_my=how_much_i_must_use else: if if_buttery_stil_has_energy+5>600: power_reference_my=if_buttery_stil_has_energy-3 else: power_reference_my=if_buttery_stil_has_energy-5 else: if_buttery_stil_has_energy=how_much_energy_battery_has-how_much_i_must_use if if_buttery_stil_has_energy>0: power_reference_my=how_much_i_must_use else: energy_of_load1=how_much_i_must_use*0.2 energy_of_load2=how_much_i_must_use*0.5 energy_of_load3=how_much_i_must_use*0.3 if_buttery_stil_has_energy=how_much_energy_battery_has-energy_of_load1 if if_buttery_stil_has_energy < 0: load_one_my=False load_two_my=False load_three_my=False power_reference_my=0; if_buttery_stil_has_energy2=if_buttery_stil_has_energy-energy_of_load2 if if_buttery_stil_has_energy2 > 0: power_reference_my=energy_of_load2+energy_of_load1 load_three_my=False else: load_two_my=False if_buttery_stil_has_energy3=if_buttery_stil_has_energy-energy_of_load3 if if_buttery_stil_has_energy2 > 0: power_reference_my=energy_of_load3+energy_of_load1 else: load_three_my=False power_reference_my=energy_of_load1 # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=load_one_my, load_two=load_two_my, load_three=load_three_my, power_reference=power_reference_my, pv_mode=pv_mode_my)
def get_physics_metrics(d: DataMessage, r: ResultsMessage, spent_time=0) \ -> Tuple[float, float, float, float, float, float, float, bool, float]: global overload_cnt global penal_l1_cnt global penal_l2_cnt BESS_MAX_POWER = 5 BESS_CAPACITY = 20 penal = 0.0 if r.power_reference > BESS_MAX_POWER: r.power_reference = BESS_MAX_POWER elif r.power_reference < -BESS_MAX_POWER: r.power_reference = -BESS_MAX_POWER if not r.load_one: if penal_l1_cnt == 0: penal += PENAL_L1_INIT + PENAL_L1_CONT penal_l1_cnt += 1 else: penal += PENAL_L1_CONT else: penal_l1_cnt = 0 if not r.load_two: if penal_l2_cnt == 0: penal += PENAL_L2_INIT + PENAL_L2_CONT penal_l2_cnt += 1 else: penal += PENAL_L2_CONT else: penal_l2_cnt = 0 if not r.load_three: penal += PENAL_L3_CONT if d.grid_status: if (d.bessSOC == 0 and r.power_reference > 0) \ or (d.bessSOC == 1 and r.power_reference < 0): r.power_reference = 0 r_load = real_load(int(r.load_one), int(r.load_two), int(r.load_three), d.current_load) mg = main_grid(True, r_load, r.power_reference, d.solar_production, r.pv_mode) # we sell if mg < 0: bess_sell = abs(mg) * d.selling_price / CFG.sampleRate consumption = 0.0 else: consumption = mg * d.buying_price / CFG.sampleRate bess_sell = 0 current_power = r.power_reference soc_bess = d.bessSOC - r.power_reference / (CFG.sampleRate * BESS_CAPACITY) overload = False elif not d.grid_status: r_load = real_load(int(r.load_one), int(r.load_two), int(r.load_three), d.current_load) current_power = main_grid(False, r_load, r.power_reference, d.solar_production, r.pv_mode) soc_bess = d.bessSOC - current_power / (CFG.sampleRate * BESS_CAPACITY) if abs(current_power) > BESS_MAX_POWER or (soc_bess >= 1 and current_power < 0) \ or (soc_bess <= 0 and current_power > 0): overload = True overload_cnt += 1 else: overload = False overload_cnt = 0 if overload_cnt > 1: penal = PENAL_L1_INIT + PENAL_L1_CONT + PENAL_L2_INIT + PENAL_L2_CONT + PENAL_L3_CONT current_power = 0 r.load_one = False r.load_two = False r.load_three = False r.pv_mode = PVMode.OFF overload = False overload_cnt = 0 soc_bess = d.bessSOC r_load = 0 consumption = 0 mg = 0 bess_sell = 0 if 0 > soc_bess: soc_bess = 0 if soc_bess > 1: soc_bess = 1 TARGET_1MS_PRICE = 100 # targeted daily price for 1ms avg spent time performance_mark = (spent_time * 1000) * (24 / (TARGET_1MS_PRICE * CFG.sampleRate)) em = energy_mark(consumption, bess_sell) pv_power = d.solar_production if r.pv_mode == PVMode.ON else 0 return em, performance_mark, mg, penal, r_load, pv_power, soc_bess, \ overload, current_power
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py global is_previous_load_one_active global is_previous_load_two_active global is_previous_load_three_active global previous_load global mins_counter global days_counter # Data Message information is_buying_price_cheap = msg.buying_price == CHEAP_BUYING_PRICE is_selling_price_positive = msg.selling_price == POSITIVE_SELLING_PRICE is_grid_status_on = msg.grid_status main_grid_power = float(msg.mainGridPower) is_battery_overload = msg.bessOverload is_battery_full = msg.bessSOC == BATTERY_MAX_CAPACITY # pred kraj prodati celu bateriju ?! # kupovati bateriju ujutru (izbaci 23 do 24 interval) # dodati neku toleranciju za trosenje baterije npr do 0.4, 5 current_load = msg.current_load is_load_rising = current_load > previous_load l1 = L1_POWER_SHARE * current_load l2 = L2_POWER_SHARE * current_load l3 = L3_POWER_SHARE * current_load l12 = l1 + l2 # 5520 : 0, 8, 3, 9.2, 0, 0.5950260191000842, False, 6.439929503154399 # 5521, 0, 8, 3, 9.199899290220571, 0, 0.5842926857667509, True, 0 # 3299, 1, 3, 3, 4.163380970229338, 0, 1.0, False, 2.909085131140325 # 3300, 1, 8, 3, 4.1708203932499375, 0.0, 1.0, False, 2.9143666791605365 load_one = True power_reference = 0.0 if not is_grid_status_on: load_three = False if is_battery_overload: load_two = False power_reference = l1 - msg.solar_production # + 0.01 else: load_two = is_previous_load_two_active if l12 - msg.solar_production < BATTERY_MAX_POWER + DELTA and not is_load_rising: load_two = True load_and_solar_diff = (l12 if load_two else l1) - msg.solar_production power_reference = load_and_solar_diff if load_and_solar_diff > 0 else 0.0 else: load_three = msg.buying_price * l3 / MINS_IN_HOUR < L3_DOWN_PENALTY load_two = True if is_buying_price_cheap: if not is_battery_full and 1 * MINS_IN_HOUR < mins_counter < 7 * MINS_IN_HOUR: power_reference = -BATTERY_MAX_POWER else: # expensive buying if l12 > 3.9: load_two = False load = l12 if load_two else l1 is_battery_prepared_for_electricity_loss = \ msg.bessSOC * 10 - DELTA > (load if load < BATTERY_MAX_POWER else BATTERY_MAX_POWER) load_and_solar_diff = load - msg.solar_production if is_battery_prepared_for_electricity_loss: power_reference = load_and_solar_diff if load_and_solar_diff < BATTERY_MAX_POWER else BATTERY_MAX_POWER # else: # # if is_selling_price_positive and main_grid_power < 0: # power_reference = -main_grid_power # if main_grid_power > -BATTERY_MAX_POWER else BATTERY_MAX_POWER pv_mode = PVMode.ON # remember this state for next step is_previous_load_one_active = load_one is_previous_load_two_active = load_two is_previous_load_three_active = load_three previous_load = current_load if mins_counter < MINS_IN_DAY: mins_counter += 1 else: mins_counter = 0 days_counter += 1 if days_counter == 4 and mins_counter > 1398: power_reference = BATTERY_MAX_POWER return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py battery = msg.bessSOC * 100 load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON #2087.19 $ #grid active if msg.grid_status: #puni se sa jeftinom strujom if battery < 99 and msg.buying_price < 5: power_reference = -5.0 #ako ima viska solarne energije, baterija se puni if msg.buying_price < 5: if (msg.solar_production >= msg.current_load): power_reference = -(msg.solar_production - msg.current_load) #ako ima premalo solarne, aktivira se baterija da pomaze if (msg.solar_production < msg.current_load): if (msg.current_load - msg.solar_production) <= 5.0: power_reference = (msg.current_load - msg.solar_production) else: power_reference = 0.0 if battery < 99 and msg.buying_price < 5: power_reference = -5.0 #koliki je minimum baterije if battery < 25: power_reference = 0.0 #ukoliko je skupa struja sta radimo if msg.buying_price > 5: if (msg.solar_production >= msg.current_load): power_reference = -(msg.solar_production - msg.current_load) #ako ima premalo solarne, aktivira se baterija da pomaze if (msg.solar_production < msg.current_load): if battery >= 10: if (msg.current_load - msg.solar_production) <= 5.0: power_reference = (msg.current_load - msg.solar_production) else: power_reference = +5.0 if battery < 99 and msg.buying_price < 5: power_reference = -5.0 ''' if battery >10 and msg.buying_price ==8: power_reference = +5.0 pv_mode = PVMode.ON if msg.solar_production > 0: if msg.solar_production > msg.current_load and msg.buying_price == 3: power_reference = -5.0 elif msg.solar_production > msg.current_load: power_reference = -(msg.solar_production - msg.current_load) else: if battery < 80 and msg.buying_price == 3: power_reference = -5.0 elif battery < 10: power_reference = 0.0 else: if msg.current_load <= 5.0: power_reference = msg.current_load else: power_reference = +5.0 else: if msg.buying_price == 8: if battery > 10: power_reference = +3.5 else: power_reference = 0.0 else: if battery < 100: power_reference = -4.99 else: power_reference = 0.0 ''' #blackout else: if msg.solar_production > 0: if msg.solar_production == msg.current_load: power_reference = 0.0 elif msg.solar_production > msg.current_load: if msg.solar_production - msg.current_load > 5: pv_mode = PVMode.OFF if msg.current_load > 5: load_three = False if msg.current_load > 5: load_two = False else: power_reference = msg.current_load else: if msg.current_load - msg.solar_production > 5.0: load_three = False if msg.current_load - msg.solar_production > 5.0: load_two = False power_reference = msg.current_load else: power_reference = msg.current_load else: load_three = False if msg.current_load <= 5.0: power_reference = msg.current_load else: load_two = False power_reference = msg.current_load return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py # Dummy result is returned in every cycle here L1,L2,L3=True,True,True p_bat = 0.0 panel=PVMode.ON if not msg.grid_status: temp=msg.solar_production+6-msg.current_load if temp<0: if temp>-0.3*msg.current_load: L3=False else: L2,L3=False,False if msg.bessSOC < 0.56: L3=False if msg.bessSOC < 0.2: L2,L3=False,False if msg.solar_production>msg.current_load and msg.bessSOC>0.99: panel=PVMode.OFF else: if msg.buying_price==3: if msg.bessSOC!=1: p_bat=-4.0 else: p_bat=0.0 else: if msg.current_load > 7.0: L2 = False if msg.solar_production < 0.3*msg.current_load: L3=False temp = msg.solar_production - msg.current_load if msg.selling_price==0: if( temp > 0): p_bat=-temp else: if temp > -4.0: p_bat=-temp else: p_bat=4.0*msg.current_load/8 else: if(temp > 0): p_bat=0.0 else: if temp > -4.0: p_bat=-temp else: p_bat=4.0*msg.current_load/8 #p_bat=4.0 if msg.bessSOC<0.2: if p_bat>0.0: p_bat=0.0 return ResultsMessage(data_msg=msg, load_one=L1, load_two=L2, load_three=L3, power_reference =p_bat, pv_mode=panel)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py power_reference = 0.0 load_three = True load_two = True load_one = True pv_mode = PVMode.ON global battery_level1 global penalty_load2 global penalty_load3 global current_load_level1 global current_load_level2 global globGridStatus, counter battery_level2 = 0.5 global battery_no_grid_level_1 global battery_no_grid_level_2 global battery_no_grid_level_3 global battery_2_cost_min_level_upper_level global battery_2_cost_min_level_lower_level real_load = calculate_real_load(msg.current_load) if msg.grid_status == False or msg.bessOverload == True: if msg.bessOverload == True or globGridStatus == True: globGridStatus = True if (msg.current_load) < 6: if msg.bessSOC > battery_no_grid_level_2: load_one = True load_two = True load_three = True power_reference = real_load elif msg.bessSOC > battery_no_grid_level_3: load_one = True load_two = True load_three = False power_reference = real_load * 0.7 elif msg.bessSOC > 0: load_one = True load_two = False load_three = False power_reference = real_load * 0.2 else: load_three = False load_two = False load_one = False power_reference = 0.0 elif (msg.current_load * 0.7) < 6: if msg.bessSOC > battery_no_grid_level_3: load_one = True load_two = True load_three = False power_reference = real_load * 0.7 elif msg.bessSOC > 0: load_one = True load_two = False load_three = False power_reference = real_load * 0.2 else: load_three = False load_two = False load_one = False power_reference = 0.0 elif (msg.current_load * 0.2) < 6: if msg.bessSOC > 0: load_one = True load_two = False load_three = False power_reference = real_load * 0.2 else: load_three = False load_two = False load_one = False power_reference = 0.0 else: load_three = False load_two = False load_one = False power_reference = 0.0 if globGridStatus is False: if msg.bessSOC > battery_no_grid_level_2: load_one = True load_two = True load_three = True power_reference = real_load elif msg.bessSOC > battery_no_grid_level_3: load_one = True load_two = True load_three = False power_reference = real_load * 0.7 elif msg.bessSOC > 0: load_one = True load_two = False load_three = False power_reference = real_load * 0.2 else: load_three = False load_two = False load_one = False power_reference = 0.0 else: ############# load managment globGridStatus = False power_source = get_power_source(msg, real_load) if power_source == PowerSource.solar: load_one = True load_two = True load_three = True power_reference = -(msg.solar_production - msg.current_load) if power_source == PowerSource.solar_battery: load_one = True load_two, load_three = calculate_load_profitability( msg.buying_price, real_load) power_reference = -(msg.solar_production - msg.current_load) power_reference = calculate_power_reference( power_reference, load_one, load_two, load_three) if power_source == PowerSource.grid_battery: load_one = True load_two, load_three = calculate_load_profitability( msg.buying_price, real_load) power_reference = -(msg.solar_production - msg.current_load) power_reference = calculate_power_reference( power_reference, load_one, load_two, load_three) if power_source == PowerSource.battery: load_one = True load_two, load_three = calculate_load_profitability( msg.buying_price, real_load) power_reference = -(msg.solar_production - msg.current_load) power_reference = calculate_power_reference( power_reference, load_one, load_two, load_three) if power_source == PowerSource.grid: tmp_load_two, tmp_load_three = calculate_load_profitability( msg.buying_price, real_load) load_two = tmp_load_two load_three = tmp_load_three if msg.buying_price < 8: power_reference = -6.0 else: power_reference = 0.0 # load_two = False # load_three = False if counter > 7100: if msg.bessSOC > 0.001: power_reference = 4.0 else: power_reference = 0.0 # tmp_load = calculate_test_load(real_load, True, tmp_load_two, tmp_load_three) # # tmp_power_source = get_power_source(msg, tmp_load) # # if tmp_power_source != power_source: # power_source = tmp_power_source # power_reference, load_one, load_two, load_three = set_loads_and_power_resource(power_source, power_reference, msg.buying_price, real_load, msg.solar_production) # # else: # if msg.buying_price < 8: # power_reference = -10.0 # else: # power_reference = 0.0 # load_three = tmp_load_three # load_two = tmp_load_two # power_reference = calculate_power_reference(power_reference, load_one, load_two, load_three) # if msg.grid_status == True: # # if penalty_load3 < 0.3 * real_load * msg.buying_price and real_load > current_load_level1: # # load_three = False # # else: # # load_three = True # # if penalty_load2 < 0.5 * real_load * msg.buying_price and real_load > current_load_level2: # # load_two = False # else: # # load_two = True # if msg.buying_price == 8 and \ # msg.solar_production > real_load: # power_reference = -(msg.solar_production - real_load) # # if msg.buying_price == 8 and \ # msg.solar_production < real_load and \ # msg.bessSOC > battery_level1: # power_reference = -(msg.solar_production - real_load) # # if msg.buying_price == 8 and \ # msg.solar_production < real_load and \ # msg.bessSOC < battery_level1: # power_reference = 0.0 # pass # # if msg.buying_price < 8 and \ # msg.solar_production < real_load and \ # msg.bessSOC > battery_2_cost_min_level_upper_level: # power_reference = real_load # # if msg.buying_price < 8 and \ # msg.solar_production < real_load and \ # msg.bessSOC < battery_2_cost_min_level_lower_level: # power_reference = -10.0 # # if load_three == False and load_two == False: # power_reference = power_reference * 0.2 # # if load_three == False and load_two == True: # power_reference = power_reference * 0.5 # # if load_three == True and load_two == False: # power_reference = power_reference * 0.7 # if counter%10: # print ("counter is ", counter, " , global flag is ", globGridStatus, "overload is ", msg.bessOverload) last_load_one = load_one last_load_two = load_two last_load_three = load_three counter = counter + 1 # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def worker(msg: DataMessage) -> ResultsMessage: """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON global blackout_happened global minBatteryLife if blackout_happened: minBatteryLife = 0.0 if blackout_happened == 1 and msg.id % 1440 == 0: blackout_happened = 0 if msg.grid_status == 0 and blackout_happened == 0: blackout_happened = 1 print('another blackout') # kada se vise isplati da placamo penale nego cenu struje if msg.buying_price > 6 and msg.current_load > 5.625: load_three = False if msg.buying_price > 6 and msg.current_load > 6.5625: load_two = False #todo pametnije odraditi if msg.current_load > 8.5 and msg.grid_status == 0.0: load_two = False load_three = False # if msg.grid_status == 0: # load_three = False # if msg.current_load < 2.5 and msg.solar_production > msg.current_load: # power_reference = msg.current_load - msg.solar_production #ukoliko je skupa struja, a mala potrosnja koristimo bateriju da bi ustedeli #ukoliko imamo viska sunca punimo bateriju if msg.buying_price > 5 and load_two and load_one and msg.bessSOC > minBatteryLife: power_reference = msg.current_load * calcPerc( load_one, load_two, load_three) - msg.solar_production if power_reference > 5.0: power_reference = 5.0 #ukoliko imamo viska solarne energije a jako je prazna baterija punimo bateriju if msg.solar_production > msg.current_load * calcPerc( load_one, load_two, load_three) and msg.bessSOC < minBatteryLife: power_reference = msg.current_load * calcPerc( load_one, load_two, load_three) - msg.solar_production # ukoliko je jeftina struja punimo bateriju do kraja if msg.buying_price < 6 and msg.bessSOC < 1: power_reference = -5.0 # ukoliko solarni panel proizvodi previse energije, cak i za sve loadove i maks punjenje baterije - gasimo panel if msg.solar_production > 5 + msg.current_load: pv_mode = pv_mode.OFF if (60 * 24 * 5 - msg.id) * 5 <= msg.bessSOC * 20 * 60: power_reference = 5.0 # Dummy result is returned in every cycle here return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def process(self, msg): state, battery, disabled = self.state_machine.state.split('_') pv_mode = PVMode.ON charge_speed = -4.0 # Ask if network changed status curr_state = 'on' if msg.grid_status else 'off' if curr_state != state: if state == 'on': self.state_machine.off() else: self.state_machine.on() # Ask if fullness changed curr_battery = battery if battery == 'full': if msg.bessSOC < 0.6: curr_battery = 'half' elif battery == 'half': if msg.bessSOC > 0.95: curr_battery = 'full' elif msg.bessSOC < 0.2: curr_battery = 'empty' else: if msg.bessSOC > 0.4: curr_battery = 'half' if curr_battery != battery: if battery != 'half': self.state_machine.half() else: if curr_battery == 'full': self.state_machine.full() else: self.state_machine.empty() # Ask if some devices should be powered on or off if state == 'on': if disabled == 'secthr': self.state_machine.third() elif disabled == 'third': self.state_machine.none() else: if msg.bessOverload and disabled == 'none': self.state_machine.third() elif msg.bessOverload and disabled == 'third': self.state_machine.secthr() elif not msg.bessOverload and msg.current_load < float( 6) and disabled == 'secthr': self.state_machine.third() elif not msg.bessOverload and msg.current_load < float( 6) and disabled == 'third': self.state_machine.none() # For different states send different controls if self.state_machine.state.startswith('on'): if self.state_machine.state == 'on_empty_none': load_two = True load_three = True if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 else: pow_ref = charge_speed elif self.state_machine.state == 'on_empty_third': load_two = True load_three = False if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 else: pow_ref = charge_speed elif self.state_machine.state == 'on_empty_secthr': load_two = False load_three = False if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 else: pow_ref = charge_speed elif self.state_machine.state == 'on_half_none': load_two = True load_three = True if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif msg.selling_price == float(3): pow_ref = 2.0 elif msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif self.state_machine.state == 'on_half_third': load_two = True load_three = False if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif msg.selling_price == float(3): pow_ref = 2.0 elif msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif self.state_machine.state == 'on_half_secthr': load_two = False load_three = False if msg.buying_price == float(8): if msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif msg.selling_price == float(3): pow_ref = 2.0 elif msg.solar_production > float(0): pow_ref = -msg.solar_production + msg.current_load else: pow_ref = 0.0 elif self.state_machine.state == 'on_full_none': load_two = True load_three = True if msg.bessSOC < float(1) and msg.buying_price < float(8): pow_ref = -6.0 else: pow_ref = 0.0 elif self.state_machine.state == 'on_full_third': load_two = True load_three = False if msg.bessSOC < float(1) and msg.buying_price < float(8): pow_ref = -6.0 else: pow_ref = 0.0 elif self.state_machine.state == 'on_full_secthr': load_two = False load_three = False if msg.bessSOC < float(1) and msg.buying_price < float(8): pow_ref = -6.0 else: pow_ref = 0.0 else: pow_ref = 0.0 if self.state_machine.state == 'off_empty_none': load_two = True load_three = True elif self.state_machine.state == 'off_empty_third': load_two = False # <-- load_three = False elif self.state_machine.state == 'off_empty_secthr': load_two = False load_three = False elif self.state_machine.state == 'off_half_none': load_two = True load_three = True elif self.state_machine.state == 'off_half_third': load_two = False # <-- load_three = False elif self.state_machine.state == 'off_half_secthr': load_two = False load_three = False elif self.state_machine.state == 'off_full_none': load_two = True load_three = True pv_mode = PVMode.OFF elif self.state_machine.state == 'off_full_third': load_two = False # <-- load_three = False pv_mode = PVMode.OFF elif self.state_machine.state == 'off_full_secthr': load_two = False load_three = False pv_mode = PVMode.OFF # Prepare response res = ResultsMessage(data_msg=msg, load_one=True, load_two=load_two, load_three=load_three, power_reference=pow_ref, pv_mode=pv_mode) print('BamBam: {}'.format(res)) print(self.state_machine.state) print(self.third_cons) print(self.sec_cons) print("=" * 50) return res
def potrosiIliProdaj(msg): load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON extra_production = msg.solar_production - msg.current_load if msg.grid_status: # radi elektrovojvodina if msg.bessSOC < min_battery_threshold: #posto imamo mrezu, stedimo bateriju maksimalno if msg.buying_price / 60.0 > 0.1: #skupa struja, gasi load3 load_three = False power_reference = -1.0 else: power_reference = -3.0 #struja je jeftina pa maksimalno punimo bateriju elif msg.bessSOC < max_battery_threshold: # baterija je ispod threshold if extra_production > 0: # panel može da puni bateriju if extra_production > 6.0: # panel daje više nego što baterija može da primi power_reference = -6.0 else: # panel daje najviše onoliko koliko baterija može da primi power_reference = -extra_production else: if msg.buying_price / 60.0 >= 0.1: # više se isplati gasiti load3 nego kupovati load_three = False current_load = msg.current_load * 0.7 new_extra_production = msg.solar_production - current_load if new_extra_production > 0: # sa isključenim load3 ima dosta struje power_reference = -extra_production else: # više se isplati kupovati struju nego gasiti load3 if msg.buying_price / 60 < 0.1: power_reference = -1.0 else: # baterija nije kritično prazna if extra_production > 0: # panel može da puni bateriju if extra_production > 6.0: # panel daje više nego što baterija može da primi power_reference = -6.0 else: # panel daje najviše onoliko koliko baterija može da primi power_reference = -extra_production else: # panel nema dovoljno energije da zadovolji load if msg.buying_price / 60.0 >= 0.1: #struja je skupa load_three = False current_load = msg.current_load * 0.7 new_extra_production = msg.solar_production - current_load if new_extra_production < -6.0: power_reference = 6.0 #ostalo kupuje iz elektrane else: power_reference = -new_extra_production #napaja ga samo baterija else: #jeftina je struja i vucemo iz elektrane if extra_production < -1.0: power_reference = 1.0 #ostalo kupuje iz elektrane else: # ne radi elektrovojvodina all_energy = msg.solar_production + 6.0 extra_production = all_energy - msg.current_load if extra_production < 0: # nema dovoljno sunca power_reference = -extra_production if msg.current_load * 0.2 > all_energy: # čak i sa samo load1 trošimo previše pa isključi sve load_one = False load_two = False load_three = False elif msg.current_load * 0.5 > all_energy: # isključenjem load2 trošimo previše load_two = False load_three = False elif msg.current_load * 0.7 <= all_energy: # dovoljno je isključiti samo load3 load_three = False else: # dovoljno je isključiti samo load2 load_two = False result = ResultsMessage( data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode, ) return result
def worker(msg: DataMessage) -> ResultsMessage: states.calc_solar_state(msg) # breakCounterLs countNoPower(msg) # racunamo razmak trenutno mesta do zadnje nule """TODO: This function should be implemented by contestants.""" # Details about DataMessage and ResultsMessage objects can be found in /utils/utils.py msg.current_load # Dummy result is returned in every cycle here #osnovna podela da li ima struje ili ne load1 = True load2 = True load3 = True power = 0.0 pv_mode = PVMode.ON if msg.buying_price > 6 and msg.current_load > 2.5: #totovo load3 = False elif msg.current_load > 6 and msg.buying_price < 6: load3 = False else: load3 = True # # if test.counter >= 1 and test.counter <= 360: #ako je dugo bilo struje mozes malo vise da prodajes # if(msg.buying_price < 6 and msg.bessSOC < 0.9): # power = chargeRate # elif msg.buying_price > 6 and msg.bessSOC > 0.15 and msg.selling_price > 1: # power = dischargeRate*1.5 if msg.buying_price > 7: if 6.5 <= msg.current_load < 6.7 and msg.bessSOC < 0.6 and msg.id % 1440 > 17 * 60: # LOAD_2 HIGH_COST BREAKPOINT if c.LOAD_2_STATE == 0: # STATE OFF c.LOAD_2_STATE = 1 c.l2_off_cost = 4 c.l2_on_cost = 0.4 load2 = False if c.LOAD_2_STATE == 1: # STATE GAINING load2 = False c.l2_off_cost += 0.4 c.l2_on_cost += msg.current_load * 0.5 * 8 / 60 if abs(c.l2_off_cost - c.l2_on_cost) < 0.5: # CLOSE ENOUGH c.LOAD_2_STATE = 2 # STATE OVERTAKING elif c.LOAD_2_STATE == 2: if msg.current_load > 6.0: load2 = False #if 6.0 <= msg.current_load < 6.1: else: c.LOAD_2_STATE = 0 load2 = True if msg.grid_status == 0: load3 = False if msg.current_load > 8.5 and msg.grid_status == 0.0: load2 = False load3 = False if msg.current_load < 2.5 and msg.solar_production > msg.current_load: power = msg.current_load - msg.solar_production if msg.bessSOC > 0.192 and msg.buying_price > 6 and msg.solar_production < msg.current_load * calcPerc( load1, load2, load3 ): #baterija puna i struja skupa i nemamo viska od solar prod -> koristimo bateriju power = -(msg.solar_production - msg.current_load * calcPerc(load1, load2, load3)) if msg.bessSOC < 0.192 and msg.grid_status is True: #ukoliko je baterija jako prazna i ima struje punimo bateriju power = chargeRate if c.solar_state == states.SolarState.BEFORE and msg.bessSOC < 0.99: # pre jutra se puni baterija power = -6.0 if load2 == False and msg.id > 1800: print('hi mom') return ResultsMessage(data_msg=msg, load_one=load1, load_two=load2, load_three=load3, power_reference=power, pv_mode=pv_mode)
def preventBessOverload(currentInput: DataMessage, previousOutput: ResultsMessage, newOutput: ResultsMessage, minBuyingPrice, maxBuyingPrice, MIN_ENERGY_FOR_BATTERY): Pbess = currentInput.current_load - currentInput.solar_production if Pbess > BATTERY_MAX_OUTPUT_POWER: if previousOutput.load_three == True: newOutput.load_three = False if currentInput.current_load * 0.7 > BATTERY_MAX_OUTPUT_POWER: newOutput.load_two = False # Case when battery is empty elif currentInput.bessSOC == 0: if currentInput.grid_status == False: turn_off_loads(newOutput) newOutput.power_reference = 0.0 availablePower = currentInput.solar_production * (-1.0) if currentInput.solar_production >= currentInput.current_load * 0.2: newOutput.load_one = True availablePower = currentInput.solar_production - currentInput.current_load * 0.2 if currentInput.solar_production >= currentInput.current_load * 0.7: newOutput.load_two = True availablePower = currentInput.solar_production - currentInput.current_load * 0.7 newOutput.power_reference = availablePower * (-1.0) else: turn_off_loads(newOutput) newOutput.power_reference = 0.0 availablePower = currentInput.solar_production if currentInput.solar_production >= currentInput.current_load * 0.2: newOutput.load_one = True availablePower = currentInput.solar_production - currentInput.current_load * 0.2 if currentInput.solar_production >= currentInput.current_load * 0.7: newOutput.load_two = True availablePower = currentInput.solar_production - currentInput.current_load * 0.7 if currentInput.solar_production >= currentInput.current_load: newOutput.load_three = True availablePower = currentInput.solar_production - currentInput.current_load newOutput.power_reference = availablePower * (-1.0) # Case when battery is full elif currentInput.bessSOC == 1: newOutput.pv_mode = PVMode.OFF handleRegularScenarios(currentInput, previousOutput, newOutput, minBuyingPrice, maxBuyingPrice, MIN_ENERGY_FOR_BATTERY) if newOutput.power_reference < 0.0: newOutput.power_reference = 0.0
def worker(msg: DataMessage) -> ResultsMessage: global prev_buyingPrice, failsafe_percentage, high_priority_failsafe_percentage, bessCap global prev_load_one, prev_load_two, prev_load_three #Init vars load_one = True load_two = True load_three = True power_reference = 0.0 pv_mode = PVMode.ON if msg.grid_status: #Grid is ONLINE # All consumers on load_one = True load_two = True load_three = True # Solar panel on pv_mode = PVMode.ON # DAY, EXPENSIVE BUYING PRICE - check if buyingPrice > prev_buyingPrice AND prev_buyingPrice <= sellingPrice if msg.buying_price > prev_buyingPrice and prev_buyingPrice <= msg.selling_price: #Reduce consumption by using previously bought power at a lower price, up until failsafe_percentage power_required = msg.current_load - msg.solar_production power_bess_can_supply = (clamp(power_required, -5.0, 5.0)) newSOC = msg.bessSOC - power_bess_can_supply/bessCap if newSOC >= failsafe_percentage: power_reference = power_bess_can_supply else: power_reference = 0.0 #NIGHT, CHEAP BUYING PRICE - check if buyingPrice < prev_buyingPrice elif msg.buying_price < prev_buyingPrice: #Charge bess to full with cheap, tasty nocturnal energy if msg.bessSOC < 1: power_reference = clamp(-((1 - msg.bessSOC) * bessCap), -5.0, 0.0) else: #GRID IS OFFLINE #print("BLACKOUT (msgid: " + str(msg.id) + ")") # Consumer three off load_one = True load_two = True load_three = False coef = 1 if prev_load_three: coef -= 0.4 if prev_load_two: coef -= 0.4 if prev_load_one: coef -= 0.2 power_required = msg.current_load * coef - msg.solar_production #print("--Init p.req: " + str(power_required)) # If solar is enough to satisfy consumption (negative power_required), excess power charges bess ---> Prevent overcharging bess # If solar is NOT enough to satisfy consumption (positive power required), help with bess kWminutes_left_in_bess = bessCap * msg.bessSOC max_draw = 5.0 #kW #print("--kWm left: " + str(kWminutes_left_in_bess)) if power_required > kWminutes_left_in_bess: #print("--1") # Kill load_two, leave load_one load_two = False # Recalc power required and assess coef = 1 if prev_load_two: coef = 0.33 power_required = msg.current_load * coef - msg.solar_production #print("----p.req: " + str(power_required)) if power_required <= kWminutes_left_in_bess and power_required <= max_draw: # Ok power_reference = power_required else: # No power left, kill one load_one = False elif power_required >= 0 and power_required <= kWminutes_left_in_bess and power_required <= max_draw: #print("--2") power_reference = power_required elif power_required >= 0 and power_required <= kWminutes_left_in_bess and power_required > max_draw: # Kill load_two, leave load_one load_two = False # Recalc power required and assess coef = 1 if prev_load_two: coef = 0.33 power_required = msg.current_load * coef - msg.solar_production # print("----p.req: " + str(power_required)) if power_required <= kWminutes_left_in_bess and power_required <= max_draw: # Ok power_reference = power_required else: # No power left, kill one load_one = False power_reference = 0 elif power_required < 0: #print("--3") # If there's more than 5 kW's for Bess, kill solar if power_required < -5: pv_mode = PVMode.OFF # Supply power solely from bess # Kill consumers if power_required > 5 power_required += msg.solar_production #print("----p.req: " + str(power_required)) if power_required > kWminutes_left_in_bess: # Kill load_two, leave load_one load_two = False # Recalc power required and assess coef = 1 if prev_load_two: coef = 0.33 power_required = msg.current_load * coef - msg.solar_production if power_required <= kWminutes_left_in_bess and power_required <= max_draw: # Ok power_reference = power_required else: # No power left, kill one load_one = False power_reference = 0 elif power_required <= kWminutes_left_in_bess and power_required <= max_draw: power_reference = power_required #print("END BLACKOUT") #print(" load_one: " + str(load_one)) #print(" load_two: " + str(load_two)) #print(" bess p.ref: " + str(power_reference)) #print(" pv_mode: " + str(pv_mode)) prev_load_one = load_one prev_load_two = load_two prev_load_three = load_three if power_reference > 5: load_two = False return ResultsMessage(data_msg=msg, load_one=load_one, load_two=load_two, load_three=load_three, power_reference=power_reference, pv_mode=pv_mode)
def handleRegularScenarios(currentInput:DataMessage, previousOutput:ResultsMessage, newOutput:ResultsMessage, minBuyingPrice, maxBuyingPrice, MIN_ENERGY_FOR_BATTERY): if currentInput.grid_status == False: if currentInput.bessSOC * 10 + currentInput.solar_production <= MINIMAL_BATTERY_POWER_FOR_LOAD_1: newOutput.load_two = False newOutput.load_three = False elif currentInput.bessSOC * 10 + currentInput.solar_production <= MINIMAL_BATTERY_POWER_FOR_LOAD_1_AND_LOAD_2: newOutput.load_three = False if currentInput.solar_production + BATTERY_MAX_OUTPUT_POWER < currentInput.current_load: newOutput.load_three = False if currentInput.solar_production + BATTERY_MAX_OUTPUT_POWER < currentInput.current_load * 0.7: newOutput.load_two = False if currentInput.solar_production + BATTERY_MAX_OUTPUT_POWER < currentInput.current_load * 0.2: newOutput.load_one = False else: extraEnergy = currentInput.solar_production - predictFutureConsumption(newOutput.load_two, newOutput.load_three, currentInput.current_load) if extraEnergy > 0: if currentInput.bessSOC * 10.0 <= 9.9: # Charge battery newOutput.power_reference = extraEnergy * (-1.0) elif currentInput.selling_price > 0: newOutput.power_reference = 0.0 else: newOutput.power_reference = 0.0 if newOutput.load_two == False and newOutput.load_three == False: if extraEnergy + 6 > currentInput.current_load * 0.8: newOutput.load_two = True newOutput.load_three = True if extraEnergy >= currentInput.current_load * 0.8: newOutput.power_reference = 0.0 elif currentInput.buying_price == maxBuyingPrice: newOutput.power_reference = currentInput.current_load * 0.8 - extraEnergy else: newOutput.load_two = False newOutput.load_three = False elif newOutput.load_two == False: if extraEnergy + 6 > currentInput.current_load * 0.5: newOutput.load_two = True if extraEnergy >= currentInput.current_load * 0.5: newOutput.power_reference = 0.0 elif currentInput.buying_price == maxBuyingPrice: newOutput.power_reference = currentInput.current_load * 0.5 - extraEnergy else: newOutput.load_two = False elif newOutput.load_three == False: if extraEnergy + 6 > currentInput.current_load * 0.3: newOutput.load_three = True if extraEnergy >= currentInput.current_load * 0.3: newOutput.power_reference = 0.0 elif currentInput.buying_price == maxBuyingPrice: newOutput.power_reference = currentInput.current_load * 0.3 - extraEnergy else: newOutput.load_three = False else: if currentInput.buying_price == minBuyingPrice and currentInput.bessSOC * 10.0 < 9.88: newOutput.power_reference = -6.0 elif currentInput.bessSOC * 10.0 > MIN_ENERGY_FOR_BATTERY: if currentInput.buying_price == maxBuyingPrice: newOutput.power_reference = extraEnergy * (-1.0) else: newOutput.power_reference = 0.0
def shutdownLoadIfPowerIsExpensive(currentInput:DataMessage, newOutput: ResultsMessage): if currentInput.buying_price * currentInput.current_load * 0.3/60 > 0.1: newOutput.load_three = False if currentInput.buying_price * currentInput.current_load * 0.5/60 > 0.4: newOutput.load_two = False