http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&feed=atom&action=history
PowerTAC Demo Agent Documentation - Revision history
2024-03-28T10:45:48Z
Revision history for this page on the wiki
MediaWiki 1.31.16
http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&diff=513&oldid=prev
Grampajohn at 17:23, 23 July 2013
2013-07-23T17:23:41Z
<p></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">Revision as of 17:23, 23 July 2013</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>= Overview =</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>= Overview =</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>This document is a guide to help developers use the PowerTAC Demo Agent - GRAILS (PDA-G) as a foundation to develop an agent for the PowerTAC platform. <del class="diffchange diffchange-inline"> </del></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">This material has been '''obsolete''' since early 2011.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>This document is a guide to help developers use the PowerTAC Demo Agent - GRAILS (PDA-G) as a foundation to develop an agent for the PowerTAC platform.  </div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>This is written under the assumption that the developer is familiar with Java and Groovy. PDA-G is developed using the GRAILS framework to take advance of its support in web-based application.  Web-based user interface is used to view agent status and control agent behavior.</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>This is written under the assumption that the developer is familiar with Java and Groovy. PDA-G is developed using the GRAILS framework to take advance of its support in web-based application.  Web-based user interface is used to view agent status and control agent behavior.</div></td></tr>
</table>
Grampajohn
http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&diff=321&oldid=prev
Nguyen Nguyen at 03:54, 29 September 2011
2011-09-29T03:54:13Z
<p></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">Revision as of 03:54, 29 September 2011</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l112" >Line 112:</td>
<td colspan="2" class="diff-lineno">Line 112:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Repeat Step 2 for  </div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Repeat Step 2 for  </div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#git clone git://github.com/powertac-plugins/powertac-common.git</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#git clone git://github.com/powertac-plugins/powertac-common.git</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;">#git clone git://github.com/powertac-plugins/powertac-server-interface.git</del></div></td><td colspan="2"> </td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#git clone git://github.com/powertac-plugins/powertac-db-stuff.git</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#git clone git://github.com/powertac-plugins/powertac-db-stuff.git</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l131" >Line 131:</td>
<td colspan="2" class="diff-lineno">Line 130:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>3) Browse to http://localhost:9090/powertac-demo-agent-grails and perform login for agent to server</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>3) Browse to http://localhost:9090/powertac-demo-agent-grails and perform login for agent to server</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>4) Browse to http://localhost:8080/powertac-server to get to server web dashbard to perform server function (<del class="diffchange diffchange-inline">ie</del>. start</div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>4) Browse to http://localhost:8080/powertac-server to get to server web dashbard to perform server function (<ins class="diffchange diffchange-inline">e.g</ins>. start</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>competition)</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>competition)</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
</table>
Nguyen Nguyen
http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&diff=320&oldid=prev
Nguyen Nguyen at 06:07, 28 September 2011
2011-09-28T06:07:19Z
<p></p>
<a href="http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&diff=320&oldid=319">Show changes</a>
Nguyen Nguyen
http://www.powertac.org/wiki/index.php?title=PowerTAC_Demo_Agent_Documentation&diff=319&oldid=prev
Nguyen Nguyen: Created page with "= Overview = This document is a guide to help developer use the PowerTAC Demo Agent - GRAILS (PDA-G) as an example to develop agent for the PowerTAC platform. This is written..."
2011-09-21T05:16:47Z
<p>Created page with "= Overview = This document is a guide to help developer use the PowerTAC Demo Agent - GRAILS (PDA-G) as an example to develop agent for the PowerTAC platform. This is written..."</p>
<p><b>New page</b></p><div>= Overview =<br />
<br />
This document is a guide to help developer use the PowerTAC Demo Agent - GRAILS (PDA-G) as an example to develop agent for the PowerTAC platform. <br />
<br />
This is written under assumption that the developer is familiar with Java and Groovy. PDA-G is developed using the GRAILS framework to take advance of its support in web-based application. Web-based user interface is used to view agent status and control agent behavior.<br />
<br />
Advantages of using PDA-G for developing an agent:<br />
*Easy to add support for new messages from server<br />
*Easy to register of message handlers<br />
*Easy to add phase activation tasks<br />
*Easy to send message to server<br />
<br />
The main goals are flexibility and ease of use. These would allow developer to concentrate on agent behavior without dealing with low level details in communication layer.<br />
<br />
There are two main events that could trigger agent action:<br />
#A particular event from the server<br />
#Phase activation<br />
<br />
== Communication with server ==<br />
Agent makes web service (WS) call to authenticate with the server using username and password. The WS call will response<br />
with URL to JMS server and agent's JMS destination name (queue name). After login, communication between server and agent<br />
is over JMS messages.<br />
<br />
== Structure ==<br />
<br />
+ grails-app/<br />
+ conf/<br />
- BuildConfig.groovy<br />
- Config.groovy<br />
+ spring/<br />
- resources.groovy<br />
+ controllers/ Agent's web controllers<br />
+ domain/ Agent's domain classes<br />
+ i18n/<br />
+ jobs/<br />
+ views/<br />
+ services/ Agent's services<br />
+ src/<br />
+ java/<br />
+ groovy/<br />
+ api/ API classes<br />
+ core/ Core package<br />
+ exceptions/ Exceptions classes<br />
+ infrastructure/ Messaging and persistence infrastructure<br />
+ interfaces/ Interfaces <br />
+ test/<br />
+ unit/<br />
+ integration/<br />
+ web-app/<br />
<br />
<br />
Each component of an agent is wired up using Spring allow easy replacement of different implementation in resource file ''grails-app/conf/spring/resources.groovy''. <br />
For example, default messagePersistenceManager uses hibernate/GORM to manage persistence. Developer could implement persistence manager that store data using a different method and replace messagePersistenceManager bean with the new class.<br />
Similar concept applies to other agent components.<br />
<br />
<syntaxhighlight lang="groovy"><br />
beans = {<br />
jmsConnectionFactory(org.springframework.jms.connection.SingleConnectionFactory) {bean -><br />
targetConnectionFactory = {org.apache.activemq.ActiveMQConnectionFactory cf -><br />
brokerURL = ''<br />
}<br />
}<br />
<br />
messageListenerRegistrar(org.powertac.broker.infrastructure.messaging.MessageListenerRegistrar)<br />
<br />
xmlMessageReceiver(org.powertac.broker.infrastructure.messaging.XMLMessageReceiver) {<br />
messageListenerRegistrar = messageListenerRegistrar<br />
messageConverter = ref('messageConverter')<br />
}<br />
<br />
messageReceiver(org.powertac.broker.infrastructure.messaging.MessageReceiver) {<br />
xmlMessageReceiver = xmlMessageReceiver<br />
}<br />
<br />
arrayListProcessor(org.powertac.broker.infrastructure.messaging.ArrayListProcessor) { bean -><br />
messageListenerRegistrar = messageListenerRegistrar<br />
}<br />
<br />
messagePersistenceManager(org.powertac.broker.infrastructure.persistence.MessagePersistenceManager)<br />
<br />
marketMessageListener(org.powertac.broker.infrastructure.messaging.MarketMessageListener) { bean -><br />
messagePersistenceManager = messagePersistenceManager<br />
}<br />
<br />
tariffNegotiator(org.powertac.broker.core.tariffnegotiator.DemoTariffNegotiator)<br />
}<br />
</syntaxhighlight><br />
<br />
= Getting started =<br />
<br />
== Checking out agent source code ==<br />
=== From github ===<br />
#cd /your/target/checkout/directory<br />
#git clone https://nnguyen@github.com/powertac/powertac-demo-agent-grails.git<br />
Repeat Step 2 for <br />
#git clone https://github.com/powertac-plugins/powertac-common.git<br />
#git clone https://github.com/powertac-plugins/powertac-server-interface.git<br />
#git clone https://github.com/powertac-plugins/powertac-db-stuff.git<br />
<br />
== Running agent in developement mode ==<br />
Note: currently, all dependency modules have to be checkout as sub-directory under one directory.<br />
<br />
1) Start an instance of the server (instruction on how to download server at [https://github.com/powertac/powertac-server/wiki/Getting-started])<br />
<br />
% cd powertac-server<br />
% grails run-app<br />
<br />
2) Start an instance of the agent (specify server.port so it would not conflict with server if server is running on the<br />
same machine)<br />
<br />
% cd powertac-demo-agent-grails<br />
% grails -Dserver.port=9090 run-app<br />
<br />
3) Browse to http://localhost:9090/powertac-demo-agent-grails and perform login for agent to server<br />
<br />
4) Browse to http://localhost:8080/powertac-server to get to server web dashbard to perform server function (ie. start<br />
competition)<br />
<br />
== Registering to event from server ==<br />
The simplest method to register to an event (message) from server is to implement ''MessageListenerWithAutoRegistration'' interface. The implementation would have a ''getMessages'' method that returns a list of interested message types and an ''onMessage'' for each of the interested message type. An example is [[#MarketMessageListener|MarketMessageListener]].<br />
<br />
== Registering to phase activation ==<br />
The simplest method to register with phase activation is to implement ''TimeslotPhaseProcessorWithAutoRegistration'' interface. The implementation would have a ''getPhases'' method that returns a list of interested phase and an ''activate'' method that take in a ''Instant'' object and a phase number that would be call when each of the interested phase is activated. An example is [[#ShoutRequestService|ShoutRequestService]].<br />
<br />
= Sample code =<br />
<br />
==MarketMessageListener==<br />
<syntaxhighlight lang="groovy"><br />
class MarketMessageListener implements MessageListenerWithAutoRegistration<br />
{<br />
private static final log = LogFactory.getLog(this)<br />
<br />
MessagePersistenceManager messagePersistenceManager<br />
static final def transientClazz = [SimEnd, ArrayList, CustomerBootstrapData,<br />
CustomerList, ErrorCmd, SimStart, SimPause, SimResume]<br />
<br />
def getMessages () {<br />
[Object]<br />
}<br />
<br />
def onMessage (Object msg) {<br />
log.debug("onMessage(${msg.class.name}) - start")<br />
if (!transientClazz.contains(msg.class)) {<br />
log.debug("onMessage(${msg.class.name}) - saving...")<br />
messagePersistenceManager.save(msg)<br />
}<br />
log.debug("onMessage(${msg.class.name}) - end")<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==MessagePersistenceManager==<br />
<syntaxhighlight lang="groovy"><br />
class MessagePersistenceManager<br />
{<br />
private static final log = LogFactory.getLog(this)<br />
private long timeslotMillis<br />
<br />
def save (Object obj) {<br />
log.warn("I don't know how to save ${obj.class.name} message type yet")<br />
}<br />
<br />
def save (WeatherReport wr) {<br />
log.debug("save(WeatherReport) - start")<br />
wr.merge()<br />
log.debug("save(WeatherReport) - end")<br />
}<br />
<br />
def save (Orderbook ob) {<br />
log.debug("save(Orderbook) - start")<br />
<br />
def asks = ob.asks.clone()<br />
def bids = ob.bids.clone()<br />
<br />
ob.asks.clear()<br />
ob.bids.clear()<br />
<br />
def timeslot = ob.timeslot<br />
if (timeslot) {<br />
timeslot.addToOrderbooks(ob)<br />
}<br />
<br />
ob.save()<br />
<br />
def processedAsks = []<br />
asks.each { ask -><br />
def dbAsk = OrderbookAsk.findById(ask.id)<br />
if (dbAsk) {<br />
ask.version = dbAsk.version<br />
ask = ask.merge()<br />
}<br />
processedAsks << ask<br />
}<br />
<br />
def processedBids = []<br />
bids.each { bid -><br />
def dbBid = OrderbookBid.findById(bid.id)<br />
if (dbBid) {<br />
bid.version = dbBid.version<br />
bid = bid.merge()<br />
}<br />
processedBids << bid<br />
}<br />
<br />
ob.bids.addAll(processedBids)<br />
ob.asks.addAll(processedAsks)<br />
<br />
log.debug("save(Orderbook) - end")<br />
}<br />
<br />
def save (CustomerInfo ci) {<br />
log.debug("save(CustomerInfo) - start")<br />
ci.merge()<br />
log.debug("save(CustomerInfo) - end")<br />
}<br />
<br />
def save (BankTransaction bt) {<br />
log.debug("save(BankTransaction) - begin")<br />
<br />
bt.merge()<br />
<br />
log.debug("save(BankTransaction) - end")<br />
}<br />
<br />
def save (CashPosition cp) {<br />
log.debug("save(CashPosition) - begin")<br />
<br />
def dbCp = CashPosition.findByBroker(cp.broker)<br />
if (dbCp) {<br />
log.debug("save(CashPosition - found in db")<br />
cp.id = dbCp.id<br />
cp.version = dbCp.version<br />
cp.merge(flush: true)<br />
} else {<br />
log.debug("save(CashPosition - NOT found in db")<br />
cp.id = null<br />
cp.save(flush: true)<br />
}<br />
log.debug("save(CashPosition) - XXXX broker ${cp?.broker?.username} has ${cp?.balance}")<br />
<br />
log.debug("save(CashPosition) - end")<br />
}<br />
<br />
def save (ClearedTrade ct) {<br />
log.debug("save(ClearedTrade) - start")<br />
<br />
def dbCt = ClearedTrade.findById(ct.id)<br />
if (dbCt) {<br />
ct.version = dbCt.version<br />
}<br />
<br />
ct.merge()<br />
<br />
log.debug("save(ClearedTrade) - end")<br />
}<br />
<br />
def save (TariffSpecification ts) {<br />
log.debug("save(TariffSpecification) - start")<br />
<br />
def processedRates = []<br />
<br />
ts.rates.each { rate -><br />
def dbRate = Rate.findById(rate.id)<br />
if (dbRate) {<br />
log.debug("save(TariffSpecification) - found [dbRate.id:${dbRate.id},dbRate.version:${dbRate.version},rate.version:${rate.version}]")<br />
rate.version = dbRate.version<br />
rate = rate.merge()<br />
log.debug("save(TariffSpecification) - after merge rate:${rate}")<br />
} else {<br />
log.debug("save(TariffSpecification) - not found rate:${rate.id}")<br />
rate.save()<br />
}<br />
processedRates << rate<br />
}<br />
<br />
log.debug("save(TariffSpecification) - there are ${ts.rates.size()} item in ts.rates")<br />
log.debug("save(TariffSpecification) - there are ${processedRates.size()} item in processedRates")<br />
<br />
ts.rates.clear()<br />
ts.rates.addAll(processedRates)<br />
<br />
if (TariffSpecification.findById(ts.id)) {<br />
ts.merge()<br />
} else {<br />
ts.save()<br />
}<br />
<br />
log.debug("save(TariffSpecification) - end")<br />
}<br />
<br />
def save (TariffTransaction ttx) {<br />
log.debug("save(TariffTransaction) - start")<br />
<br />
ttx.merge()<br />
<br />
log.debug("save(TariffTransaction) - receving ${ttx.txType} ttx for ${ttx.broker.username}")<br />
log.debug("save(TariffTransaction) - end")<br />
<br />
}<br />
<br />
def save (TariffStatus ts) {<br />
log.debug("save(TariffStatus) - start")<br />
<br />
ts.merge()<br />
<br />
log.debug("save(TariffStatus) - start")<br />
}<br />
<br />
<br />
def save (Competition competition) {<br />
log.debug("save(Competition) - start")<br />
<br />
competition.brokers?.each {<br />
log.debug("save(Competition) - populate broker: ${it}")<br />
def broker = new Broker(username: it, enabled: true)<br />
broker.save()<br />
}<br />
<br />
timeslotMillis = competition.timeslotLength * TimeService.MINUTE<br />
<br />
log.debug("save(Competition) - saving competition ${competition}:${competition.save() ? 'successful' : competition.errors}")<br />
log.debug("save(Competition) - end")<br />
}<br />
<br />
def save (SimStart simStart) {<br />
log.debug("save(SimStart) - start")<br />
log.debug("Saving simStart - start @ ${simStart.start}")<br />
<br />
simStart.save()<br />
<br />
log.debug("save(SimStart) - this: ${this}")<br />
log.debug("save(SimStart) - end")<br />
}<br />
<br />
def save (TimeslotUpdate slotUpdate) {<br />
log.debug("save(TimeslotUpdate) - start")<br />
<br />
log.debug("save(TimeslotUpdate) - received TimeslotUpdate: ${slotUpdate.id}")<br />
<br />
def newEnableds = []<br />
slotUpdate.enabled?.each {<br />
it.id = it.serialNumber<br />
it.enabled = true<br />
it.endInstant = it.startInstant + timeslotMillis<br />
log.debug("save(TimeslotUpdate) - saving enabled timeslot ${it.id}: ${(newEnableds << it.merge()) ? 'successful' : it.errors}")<br />
}<br />
slotUpdate.enabled = newEnableds<br />
<br />
def newDisables = []<br />
slotUpdate.disabled?.each {<br />
def dbTimeslot = Timeslot.findBySerialNumber(it.serialNumber)<br />
it.id = it.serialNumber<br />
it.enabled = false<br />
it.endInstant = it.startInstant + timeslotMillis<br />
it.version = dbTimeslot.version<br />
log.debug("save(TimeslotUpdate) - saving disabled timeslot ${it.id}: ${(newDisables << it.merge()) ? 'successful' : it.errors}")<br />
}<br />
slotUpdate.disabled = newDisables<br />
<br />
log.debug("save(TimeslotUpdate) - saving TimeslotUpdate ${slotUpdate.id}:${slotUpdate.save() ? 'successful' : slotUpdate.errors}")<br />
<br />
log.debug("save(TimeslotUpdate) - end")<br />
}<br />
<br />
def save (BalancingTransaction bt) {<br />
log.debug("save(BalancingTransaction) - not yet implemented")<br />
}<br />
<br />
def save (DistributionTransaction dt) {<br />
log.debug("save(DistributionTransaction) - not yet implemented")<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==ShoutRequestService== <br />
<syntaxhighlight lang="groovy"><br />
class ShoutRequestService implements TimeslotPhaseProcessorWithAutoRegistration<br />
{<br />
static transactional = true<br />
<br />
def jmsManagementService<br />
<br />
def getPhases() {<br />
[1]<br />
}<br />
<br />
void activate (Instant time, int phaseNumber) {<br />
Timeslot timeslot = getTimeSlot(time)<br />
if (timeslot) {<br />
def shouts = ShoutRequest.findAllActiveAtTimeslot(timeslot.serialNumber).list()<br />
shouts?.each { shoutRequest -><br />
log.debug("activate - shout: ${shoutRequest}")<br />
def shout = new Shout(shoutRequest.properties)<br />
shout.broker = Broker.findByUsername(ConfigurationHolder.config.powertac.username)<br />
shout.timeslot = getTimeSlot(time)<br />
jmsManagementService.send(shout)<br />
}<br />
}<br />
}<br />
<br />
def getTimeSlot(time) {<br />
def competition = Competition.currentCompetition()<br />
def timeslot = null<br />
if (competition) {<br />
def startTime = competition.simulationBaseTime<br />
int numTimeslots = (time.millis - startTime.millis) / (competition.timeslotLength * TimeService.MINUTE)<br />
log.debug("startTime: ${startTime}, currentTime: ${time}, numTimeslots: ${numTimeslots}")<br />
timeslot = new Timeslot(serialNumber: numTimeslots + 1)<br />
}<br />
return timeslot<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
= Reference material =<br />
<pre><br />
./services/org/powertac/broker/GameStateService.groovy Service for retrieve/update GameState <br />
./services/org/powertac/broker/PauseActionStateService.groovy Service for pausing game functionality<br />
./services/org/powertac/broker/TimeslotPhaseService.groovy Service for time slot phase activation<br />
./services/org/powertac/broker/CashPositionService.groovy Service for retrieve/update CashPosition<br />
./services/org/powertac/broker/ConnectionService.groovy Service for connection management<br />
./services/org/powertac/broker/JmsManagementService.groovy Service for JMS management<br />
./services/org/powertac/broker/AutoLoginService.groovy Service for auto login functionality<br />
./services/org/powertac/broker/ShoutRequestService.groovy Service for requesting shout<br />
./services/org/powertac/broker/CompetitionManagementService.groovy Service for managing competition<br />
./services/org/powertac/broker/TariffPublishingService.groovy Service for publishing tarifff to server<br />
./jobs/org/powertac/broker/LoginJob.groovy Task for auto login<br />
./jobs/org/powertac/broker/ClockDriveJob.groovy Task for time slot management<br />
./conf/UrlMappings.groovy Url mapping configuration file<br />
./conf/BootStrap.groovy Bootstrap file<br />
./conf/Config.groovy Project configuration file<br />
./conf/DataSource.groovy Datasource configuration file<br />
./conf/BuildConfig.groovy Build/dependency configuration file<br />
./conf/QuartzConfig.groovy Timer service configuration file<br />
./conf/spring/resources.groovy Spring resource file<br />
./domain/org/powertac/broker/ShoutRequest.groovy Domain class for ShoutRequest<br />
./domain/org/powertac/broker/PauseActionState.groovy Domain class for PauseActionState<br />
./domain/org/powertac/broker/GameState.groovy Domain class for GameState<br />
./controllers/org/powertac/broker/ShoutRequestController.groovy Web controller for ShoutRequest<br />
./controllers/org/powertac/broker/StatusController.groovy Web controller for conntection/login status<br />
./controllers/org/powertac/broker/TariffPublisherController.groovy Web controller for tarriff publishing<br />
./controllers/org/powertac/broker/ConnectionController.groovy Web controller for connection management<br />
./controllers/org/powertac/broker/GameStatusController.groovy Web controller for game status<br />
</pre><br />
<br />
= FAQ =<br />
<br />
* How to run a non-web-based agent?<br />
The web interface is only there to help with ease of agent development. Agents could be developed without using the web interface. <br />
<br />
* What relevant source files control the demo agent's behaviour?<br />
Agent behavior can be controlled with both asynchronous events and periodic events.<br />
* Asynchronous events come from messages from the server such as TariffSpecification, Orderbook, etc.<br />
* Periodic events come from registered tasks to be executed for each timeslot.<br />
<br />
* Any other recommendations for getting started tuning / developing an<br />
agent?<br />
Kang, P. "Software Architecture of the TAC Energy Trading Broker", August 5, 2010</div>
Nguyen Nguyen