<?xml version='1.0' encoding='UTF-8'?>
<simconf version="2022112801">
  <simulation>
    <title>Battery-leaf story: join, useful reading, relay off, path heals</title>
    <randomseed>1</randomseed>
    <motedelay_us>1000000</motedelay_us>
    <radiomedium>
      org.contikios.cooja.radiomediums.UDGM
      <transmitting_range>50.0</transmitting_range>
      <interference_range>50.0</interference_range>
      <success_ratio_tx>1.0</success_ratio_tx>
      <success_ratio_rx>1.0</success_ratio_rx>
    </radiomedium>
    <events>
      <logoutput>40000</logoutput>
    </events>
    <motetype>
      org.contikios.cooja.contikimote.ContikiMoteType
      <description>Root 1</description>
      <source>[CONFIG_DIR]/routers/udp-server.c</source>
      <commands>make TARGET=cooja clean
make -j4 udp-server.cooja TARGET=cooja</commands>
      <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="0" y="0" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>1</id>
        </interface_config>
      </mote>
    </motetype>
    <motetype>
      org.contikios.cooja.contikimote.ContikiMoteType
      <description>Powered relays 2 and 3</description>
      <source>[CONFIG_DIR]/routers/udp-client.c</source>
      <commands>make TARGET=cooja clean
make -j4 udp-client.cooja TARGET=cooja</commands>
      <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="-30" y="25" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>2</id>
        </interface_config>
      </mote>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="30" y="25" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>3</id>
        </interface_config>
      </mote>
    </motetype>
    <motetype>
      org.contikios.cooja.contikimote.ContikiMoteType
      <description>Battery-role leaf 5; injected temperature</description>
      <source>[CONFIG_DIR]/sensor/udp-client.c</source>
      <commands>make TARGET=cooja clean
make -j4 udp-client.cooja TARGET=cooja</commands>
      <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="300" y="300" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>5</id>
        </interface_config>
      </mote>
    </motetype>
  </simulation>
  <plugin>org.contikios.cooja.plugins.Visualizer<plugin_config>
      <skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
      <viewport>4.0 0.0 0.0 4.0 490.0 80.0</viewport>
      <moterelations />
    </plugin_config>
    <bounds x="0" y="0" width="1000" height="475" z="1" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.LogListener<plugin_config>
      <filter>Received request|Received response|#L</filter>
      <formatted_time />
      <coloring />
    </plugin_config>
    <bounds x="0" y="480" width="1580" height="430" z="0" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.Notes<plugin_config>
      <notes>At 30 s leaf 5 moves into range; only relays can reach it.
Injected reading temperature_c=21.5; no physical sensor.
GUI pauses at 110 s: capture then click Start/Pause.
At 120 s the actual preferred relay is switched off.
Observe replacement parent, first recovered reading and reply.
RPL analogy only: no Zigbee commissioning or Matter stack.</notes>
      <decorations>true</decorations>
    </plugin_config>
    <bounds x="1005" y="0" width="575" height="215" z="3" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.ScriptRunner<plugin_config>
      <script>sources={}; replies={}; sent=0; received=0; parents={}; measurements={};
TIMEOUT(240000, log.log("SUMMARY duration_us="+sim.getSimulationTime()+" sent="+sent+" root_received="+received+" clients="+Object.keys(sources).length+" reply_clients="+Object.keys(replies).length+" parents="+JSON.stringify(parents)+" measurements="+JSON.stringify(measurements)+"\n"); if(measurements.firstReading_us&lt;measurements.fault_us &amp;&amp; measurements.changed_us &amp;&amp; measurements.recoveredReading_us &amp;&amp; measurements.recoveredReply_us &amp;&amp; measurements.ping) log.testOK(); else log.testFailed());
GENERATE_MSG(30000, "EVENT bring-battery-leaf-in-range");
GENERATE_MSG(105000, "EVENT joined-status");
GENERATE_MSG(106000, "EVENT joined-neighbors");
GENERATE_MSG(110000, "EVENT GUI-joined-pause");
GENERATE_MSG(120000, "EVENT switch-off-selected-relay");
GENERATE_MSG(220000, "EVENT healed-status");
GENERATE_MSG(225000, "EVENT healed-ping");
while(true) {
 YIELD(); msg=String(msg); log.log(time+" ID:"+id+" "+msg+"\n");
 if(msg.indexOf("Sending request")&gt;=0) sent++;
 if(id==1 &amp;&amp; msg.indexOf("Received request")&gt;=0) { received++; sources[msg.split(" from ")[1]]=true; }
 if(id!=1 &amp;&amp; msg.indexOf("Received response")&gt;=0) replies[id]=true;
 var match=msg.match(/#L (\d+) 1/); if(match) parents[id]=Number(match[1]);
 if(msg=="EVENT bring-battery-leaf-in-range") { sim.getMoteWithID(5).getInterfaces().getPosition().setCoordinates(0,55,0); measurements.joinStart_us=time; }
 if(msg=="EVENT joined-status") { write(sim.getMoteWithID(5),"rpl-status"); }
 if(msg=="EVENT joined-neighbors") { write(sim.getMoteWithID(5),"rpl-nbr"); }
 if(msg=="EVENT GUI-joined-pause") { if(Java.type("org.contikios.cooja.Cooja").isVisualized()) sim.stopSimulation(); }
 if(msg=="EVENT switch-off-selected-relay") { measurements.oldParent=parents[5]; sim.removeMote(sim.getMoteWithID(measurements.oldParent)); measurements.fault_us=time; log.log("FAULT switched_off_relay="+measurements.oldParent+" at_us="+time+"\n"); }
 if(msg=="EVENT healed-status") { write(sim.getMoteWithID(5),"rpl-status"); }
 if(msg=="EVENT healed-ping") { write(sim.getMoteWithID(5),"ping fd00::201:1:1:1"); }

var removed=msg.match(/#L (\d+) 0/); if(removed &amp;&amp; parents[id]==Number(removed[1])) delete parents[id];
if(id==5 &amp;&amp; match &amp;&amp; !measurements.firstParent_us) { measurements.firstParent_us=time;measurements.firstParent=Number(match[1]); }
if(id==1 &amp;&amp; msg.indexOf("Received request 'temperature_c=21.5")&gt;=0) { if(!measurements.firstReading_us) measurements.firstReading_us=time; if(measurements.fault_us &amp;&amp; !measurements.recoveredReading_us) measurements.recoveredReading_us=time; measurements.readings=(measurements.readings||0)+1; }
if(id==5 &amp;&amp; msg.indexOf("Received response 'temperature_c=21.5")&gt;=0 &amp;&amp; measurements.fault_us &amp;&amp; !measurements.recoveredReply_us) measurements.recoveredReply_us=time;
if(id==5 &amp;&amp; match &amp;&amp; measurements.fault_us &amp;&amp; Number(match[1])!=measurements.oldParent &amp;&amp; !measurements.changed_us) { measurements.changed_us=time;measurements.newParent=Number(match[1]); }
if(id==5 &amp;&amp; msg.indexOf("Received ping reply")&gt;=0) measurements.ping=msg;

}
</script>
      <active>true</active>
    </plugin_config>
    <bounds x="1005" y="220" width="575" height="255" z="4" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.RadioLogger<plugin_config>
      <split>150</split>
    </plugin_config>
    <bounds x="0" y="0" width="1580" height="475" z="5" />
  </plugin>
</simconf>