The most natural place to keep track of energy would be in the PHYSICAL (phy) agent. Assuming you are using the HalfDuplexModem phy in a UnetSim, I'd subclass it and monitor the TxFrameNtf and RxFrameNtf by overriding the send() method. I'd then add relevant energy attribute to keep track of the energy usage.
Example Groovy code:
import org.arl.fjage.Message
import org.arl.unet.sim.HalfDuplexModem
class MyHalfDuplexModem extends HalfDuplexModem {
  float energy = 1000   // change to whatever initial energy your node has
  @Override
  boolean send(Message m) {
    if (m instanceof TxFrameNtf) energy -= 10  // change according to your model
    if (m instanceof RxFrameNtf) energy -= 1   // change according to your model
    return super.send(m)
  }
}
Finally, in the simulation DSL, you can replace the default HalfDuplexModem by your customized version:
modem.model = MyHalfDuplexModem