/* * Copyright: Almende B.V. (2014), Rotterdam, The Netherlands * License: The Apache Software License, Version 2.0 */ package com.almende.eve.ggdemo; import java.io.IOException; import java.net.URI; import java.util.List; import org.joda.time.DateTime; import com.almende.eve.algorithms.DAA; import com.almende.eve.algorithms.DAAValueBean; import com.almende.eve.algorithms.TrickleRPC; import com.almende.eve.protocol.jsonrpc.annotation.Name; import com.almende.eve.protocol.jsonrpc.annotation.Namespace; import com.almende.eve.protocol.jsonrpc.annotation.Optional; import com.almende.eve.protocol.jsonrpc.formats.JSONRPCException; import com.almende.eve.protocol.jsonrpc.formats.Params; import com.almende.util.URIUtil; import com.almende.util.jackson.JOM; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ObjectNode; /** * The Class DAALampAgent. */ public class DAALampAgent extends AbstractLampAgent { private DAA lampCnt = new DAA(); private DAA onCnt = new DAA(); private TrickleRPC trickle = null; private double percent = 0.0; /* * (non-Javadoc) * @see * com.almende.eve.ggdemo.LampAgent#handleGoal(com.almende.eve.ggdemo.Goal, * java.lang.String) */ @Override public void handleGoal(Goal goal, URI sender) throws JSONRPCException, JsonProcessingException, IOException { if (neighbours == null) { neighbours = getNeighbours(); } Goal oldgoal = getState().get("goal", Goal.class); if (oldgoal != null && oldgoal.getId().equals(goal.getId())) { // EARLY exist, seen this goal before. return; } getState().put("goal", goal); percent = goal.getGoalPct(); for (String neighbour : neighbours) { ObjectNode params = JOM.createObjectNode(); params.set("goal", JOM.getInstance().valueToTree(goal)); call(URIUtil.create(neighbour), "handleGoal", params, null); } } private void setOnValue(double value) { onCnt.setNewValue(value); } public void scheduleLamps(){ checkLamps(); schedule("scheduleLamps", null, 1000+Math.round(Math.random()*5000)); } private void checkLamps() { long requiredOn = Math.round((percent * lampCnt.computeSum()) / 100); long diff = requiredOn - Math.round(onCnt.computeSum()); System.out.println(getId()+": diff:"+diff+"/"+requiredOn+" on total:"+Math.round(lampCnt.computeSum())); if (diff > 0) { if (!super.isOn()) { lampOn(); setOnValue(1.0); trickle.reset(); System.out.print("!"); } } else if (diff < 0) { if (super.isOn()) { lampOff(); setOnValue(0.0); trickle.reset(); System.out.print("."); } } } @Override public void create(List<String> neighbours, Integer stepSize) throws JSONRPCException, IOException { super.create(neighbours, stepSize); final ObjectNode config = JOM.createObjectNode(); config.put("width", 1000); config.put("initialTTL", 10); config.put("evictionFactor", 20); config.put("intervalFactor", 5); config.put("intervalMin", 200); config.put("redundancyFactor", 999); lampCnt.configure(config); lampCnt.setNewValue(1.0); onCnt.configure(config); onCnt.setNewValue(super.isOn() ? 1.0 : 0.0); final List<String> nbs = neighbours; trickle = new TrickleRPC(config, getScheduler(), new Runnable() { @Override public void run() { //checkLamps(); final long delay = (long) (trickle.getDelay() * 3.2); lampCnt.getLocalValue().setTTL( DateTime.now().plus(delay).getMillis()); onCnt.getLocalValue().setTTL( DateTime.now().plus(delay).getMillis()); } }, new Runnable() { @Override public void run() { for (final String neighbour : nbs) { Params params = new Params(); params.add("nofLamps", lampCnt.getCurrentEstimate()); params.add("nofOn", onCnt.getCurrentEstimate()); try { call(URIUtil.create(neighbour), "daaReceive", params); } catch (IOException e) {} } } }); scheduleLamps(); } /** * Gets the trickle. * * @return the trickle */ @Namespace("*") public TrickleRPC getTrickle() { return trickle; } /** * Daa receive. * * @param nofLamps * the nof lamps * @param nofOn * the nof on * @throws JsonProcessingException * the json processing exception */ public void daaReceive(@Name("nofLamps") @Optional DAAValueBean nofLamps, @Name("nofOn") @Optional DAAValueBean nofOn) throws JsonProcessingException { if (nofLamps == null) { nofLamps = lampCnt.getCurrentEstimate(); } if (nofOn == null) { nofOn = onCnt.getCurrentEstimate(); } double oldNofLamps = 0.0; if (lampCnt.getCurrentEstimate() != null) { oldNofLamps = lampCnt.getCurrentEstimate().computeSum(); } double oldNofOn = 0.0; if (onCnt.getCurrentEstimate() != null) { oldNofOn = onCnt.getCurrentEstimate().computeSum(); } lampCnt.receive(nofLamps); onCnt.receive(nofOn); if (trickle != null) { if (oldNofLamps != lampCnt.getCurrentEstimate().computeSum() || oldNofOn != onCnt.getCurrentEstimate().computeSum()) { trickle.reset(); } else { trickle.incr(); } } } }