private double[] getTsCoefficients (Timeslot slot) { int horizon = timeslotCoefficients.length; if (-1 == ringOffset) { // first encounter ringOffset = slot.getSerialNumber(); lastTsGenerated = slot.getSerialNumber(); walkCoefficients(getCoefficientArray(), timeslotCoefficients[0]); logCoefficients(slot.getSerialNumber(), timeslotCoefficients[0]); } int index = (slot.getSerialNumber() - ringOffset) % horizon; if (slot.getSerialNumber() > lastTsGenerated) { int prev = (slot.getSerialNumber() - ringOffset - 1) % horizon; walkCoefficients(timeslotCoefficients[prev], timeslotCoefficients[index]); logCoefficients(slot.getSerialNumber(), timeslotCoefficients[index]); lastTsGenerated = slot.getSerialNumber(); } return timeslotCoefficients[index]; }
private TimeslotUpdate makeTimeslotUpdate () { List<Timeslot> enabled = timeslotRepo.enabledTimeslots(); TimeslotUpdate msg = new TimeslotUpdate(timeService.getCurrentTime(), enabled.get(0).getSerialNumber(), enabled.get(enabled.size() - 1).getSerialNumber()); return msg; }
private void overwriteForecastCapacities (Timeslot timeslot, CapacityProfile profile) { Timeslot slider = timeslot; for (int i = 0; i < CapacityProfile.NUM_TIMESLOTS; ++i) { forecastCapacities.put(slider.getSerialNumber(), profile.getCapacity(i)); slider = timeslotRepo.getNext(slider); } }
@Override public void postEconomicControl (EconomicControlEvent event) { int tsIndex = event.getTimeslotIndex(); int current = timeslotRepo.currentTimeslot().getSerialNumber(); if (tsIndex < current) { log.warn("attempt to save old economic control for ts " + tsIndex + " during timeslot " + current); return; } List<EconomicControlEvent> tsList = pendingEconomicControls.get(tsIndex); if (null == tsList) { tsList = new ArrayList<EconomicControlEvent>(); pendingEconomicControls.put(tsIndex, tsList); } tsList.add(event); }
private void submitOrder (double neededKWh, Timeslot timeslot) { double neededMWh = neededKWh / 1000.0; if (Math.abs(neededMWh) < competition.getMinimumOrderQuantity()) { // don't bother return; } Double limitPrice; MarketPosition posn = face.findMarketPositionByTimeslot(timeslot.getSerialNumber()); if (posn != null) neededMWh -= posn.getOverallBalance(); log.debug("needed mWh=" + neededMWh); if (Math.abs(neededMWh) < minMWh) { log.info("no power required in timeslot " + timeslot.getSerialNumber()); return; } else { limitPrice = computeLimitPrice(timeslot, neededMWh); } log.info("new order for " + neededMWh + " at " + limitPrice + " in timeslot " + timeslot.getSerialNumber()); Order result = new Order(face, timeslot.getSerialNumber(), neededMWh, limitPrice); lastOrder.put(timeslot, result); brokerProxyService.routeMessage(result); }
/** * Gets the net market position for the current timeslot. This only works on * processed transactions, but it can be used before activation in case there * can be no new market transactions for the current timeslot. This is the * normal case. The value will be positive if the broker is importing power * during the current timeslot. */ @Override public synchronized double getCurrentMarketPosition(Broker broker) { Timeslot current = timeslotRepo.currentTimeslot(); log.debug("current timeslot: " + current.getSerialNumber()); MarketPosition position = broker.findMarketPositionByTimeslot(current.getSerialNumber()); if (position == null) { log.debug("null position for ts " + current.getSerialNumber()); return 0.0; } log.info("market position for " + broker.getUsername() + ": " + position.getOverallBalance()); return position.getOverallBalance(); }
if (next.getSerialNumber() > expectedIndex) { int missingTicks = next.getSerialNumber() - expectedIndex; log.error("Missed " + missingTicks + " ticks - adjusting"); stop();
@Override public void evaluateTariffs () { Timeslot timeslot = getTimeslotRepo().currentTimeslot(); log.info("Customer " + getName() + " evaluating tariffs at timeslot " + timeslot.getSerialNumber()); utilityOptimizer.evaluateTariffs(); }
private void overwriteForecastCapacitiesPerSub (Timeslot timeslot, CapacityProfile profile, TariffSubscription sub) { Timeslot slider = timeslot; for (int i = 0; i < CapacityProfile.NUM_TIMESLOTS; ++i) { int futureTimeslot = slider.getSerialNumber(); double futureCapacity = profile.getCapacity(i); insertIntoForecastCapacitiesPerSub(sub, futureTimeslot, futureCapacity); slider = timeslotRepo.getNext(slider); } }
public void consumePower () { Timeslot ts = service.getTimeslotRepo().currentTimeslot(); int serial; for (CustomerInfo customer: getCustomerInfos()) { List<TariffSubscription> subscriptions = service.getTariffSubscriptionRepo() .findActiveSubscriptionsForCustomer(customer); String temp = officeMapping.get(customer); String type = temp.substring(0, 2); boolean controllable = temp.contains("Controllable"); if (ts == null) { log.error("Current timeslot is null"); serial = 0; } else { log.debug("Timeslot Serial: " + ts.getSerialNumber()); serial = ts.getSerialNumber(); } double load = getConsumptionByTimeslot(serial, type, controllable); log.debug("Consumption Load for Customer " + customer.toString() + ": " + load + " for subscriptions " + subscriptions.toString()); if (subscriptions != null && subscriptions.size() != 0) { subscriptions.get(0).usePower(load); } } }
@Override public void handleNewTimeslot () { Timeslot timeslot = getTimeslotRepo().currentTimeslot(); log.info("Customer " + getName() + " activated for timeslot " + timeslot.getSerialNumber()); utilityOptimizer.handleNewTimeslot(timeslot); }
log.debug("Timeslot Serial: " + ts.getSerialNumber()); serial = ts.getSerialNumber();
/** * Generates buy orders. Price is distributed exponentially with a mean value * of priceBeta. Quantity is mwh/price. */ @Override public void generateOrders (Instant now, List<Timeslot> openSlots) { log.info("generate orders for " + getUsername()); for (Timeslot slot : openSlots) { int slotNum = slot.getSerialNumber(); double price = - priceBeta * Math.log(1.0 - seed.nextDouble()); double qty = mwh / price; if (Math.abs(qty) < Competition.currentCompetition() .getMinimumOrderQuantity()) return; Order offer = new Order(this, slotNum, qty, -price); log.debug(getUsername() + " wants " + qty + " in " + slotNum + " for " + price); brokerProxyService.routeMessage(offer); } }
function.setCoefficients(getTsCoefficients(slot)); MarketPosition posn = findMarketPositionByTimeslot(slot.getSerialNumber()); double start = 0.0; if (posn != null) { double std = dx * getQSigma(); dx = Math.max(0.0, ran[1] * std + dx); // don't go backward Order offer = new Order(this, slot.getSerialNumber(), -dx, price); log.debug("new order (ts, qty, price): (" + slot.getSerialNumber() + ", " + (-dx) + ", " + price + ")"); brokerProxyService.routeMessage(offer);
int oldSerial = (current.getSerialNumber() + competition.getDeactivateTimeslotsAhead() - 1); Timeslot oldTs = timeslotRepo.findBySerialNumber(oldSerial); int newSerial = (current.getSerialNumber() + competition.getDeactivateTimeslotsAhead() - 1 + competition.getTimeslotsOpen()); log.info("newTS null in activateNextTimeslot"); long start = (current.getStartInstant().getMillis() + (newSerial - current.getSerialNumber()) * timeslotMillis); newTs = timeslotRepo.makeTimeslot(new Instant(start)); return current.getSerialNumber();
@Override public void activate (Instant time, int phaseNumber) { log.info("Activate"); List<Broker> brokerList = brokerRepo.findRetailBrokers(); if (brokerList == null) { log.error("Failed to retrieve retail broker list"); return; } // create the BalanceReport to carry the total imbalance Timeslot current = timeslotRepo.currentTimeslot(); DoubleWrapper sum = makeDoubleWrapper(); // Run the balancing market // Transactions are posted to the Accounting Service and Brokers are // notified of balancing transactions balancingResults = balanceTimeslot(brokerList, sum); // Send the balance report BalanceReport report = new BalanceReport(current.getSerialNumber(), sum.getValue()); brokerProxyService.broadcastMessage(report); }
/** * Generates Orders in the market to sell remaining available capacity. */ public void generateOrders (Instant now, List<Timeslot> openSlots) { log.info("Generate orders for " + getUsername()); double[] tempCorrections = computeWeatherCorrections(); int i = 0; for (Timeslot slot: openSlots) { int index = slot.getSerialNumber(); MarketPosition posn = findMarketPositionByTimeslot(index); double start = 0.0; double demand = computeScaledValue(index, tempCorrections[i++]); if (posn != null) { // posn.overallBalance is negative if we have sold power in this slot start = posn.getOverallBalance(); } double needed = demand - start; Order offer = new Order(this, index, needed, null); log.info(getUsername() + " orders " + needed + " ts " + index); brokerProxyService.routeMessage(offer); } }
skip = 0; for (Timeslot slot : openSlots) { int slotNum = slot.getSerialNumber(); double availableCapacity = currentCapacity;
private void updateBrokerMarketPosition(MarketTransaction tx) { Broker broker = tx.getBroker(); MarketPosition mkt = broker.findMarketPositionByTimeslot(tx.getTimeslotIndex()); if (mkt == null) { mkt = new MarketPosition(broker, tx.getTimeslot(), tx.getMWh()); log.debug("New MarketPosition(" + broker.getUsername() + ", " + tx.getTimeslot().getSerialNumber() + "): " + mkt.getId()); broker.addMarketPosition(mkt, tx.getTimeslotIndex()); } else { mkt.updateBalance(tx.getMWh()); } }
/** * Processes an incoming ControlEvent from a broker */ public synchronized void handleMessage (EconomicControlEvent msg) { ValidationResult result = validateUpdate(msg); if (result.tariff == null) { send(result.message); return; } int currentTimeslot = timeslotRepo.currentTimeslot().getSerialNumber(); if (currentTimeslot > msg.getTimeslotIndex()) { // this is in the past log.warn("Curtailment requested in ts " + currentTimeslot + " for past timeslot " + msg.getTimeslotIndex()); // send error? send(new TariffStatus(msg.getBroker(), msg.getTariffId(), msg.getId(), TariffStatus.Status.invalidUpdate) .withMessage("control: specified timeslot in the past")); return; } capacityControlService.postEconomicControl(msg); }