1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
#!/usr/bin/env python
from .node_plugin import NodePlugin
# PowerStates allows you to measure the energy consumption of a
# node that go through several power states during the simulation
# Two version of Powerstates is provided by mean of two classes:
# - Powerstates: Allow you to set power to any user's defined values
# - PowerstatesFromFile: Allow you to set power from states defined in a file
######################
# _ ____ ___ #
# / \ | _ \_ _| #
# / _ \ | |_) | | #
# / ___ \| __/| | #
# /_/ \_\_| |___| #
# #
######################
# #Regarding PowerStates:
# import Powerstates as ps
# pstates=ps.PowerStates(<node>,<power_init>)
# pstates.set_power(<power>) # Switch the power consumption to <power>
# pstates.report_energy() # Display the current node energy consumption up to the current simulated time
# pstates.report_power_changes() # Display all the power changes up to the current simulated time
# #Regarding PowerStatesFromFile:
# #Format of <file> is one <entry> per line that follow this format <state-0>:<state-1>:...:<state-n>
# #Each line can corresponds to one node (line 0 for node 0 etc..)
# import Powerstates as ps
# pstates=ps.PowerStatesFromFile(<node>,<file>,<entry-line>) # Create a power states on node <node> using line <entry-line> of file <file>
# pstates.set_state(<id>) # Switch to the <id> power states
# pstates.report_energy() # Display the current node energy consumption up to the current simulated time
# pstates.report_power_changes() # Display all the power changes up to the current simulated time
# pstates.report_state_changes() # Display all the states changes up to the current simulated time
class PowerStates(NodePlugin):
"""
PowerStates model the energy consumed by the various changes of power consumption of a node over time.
"""
def __init__(self,node,power_init):
self.node=node
self.clock=self.node.read("clock")
self.energy=0
self.power=power_init
self.power_changes=dict()
self.set_power(power_init)
super().__init__("Powerstates",api)
def set_power(self,power_watt):
cur_clock=self.node.read("clock")
self.energy+=self.power*(cur_clock-self.clock)
self.clock=cur_clock
if self.power != power_watt:
self.power_changes[cur_clock]=power_watt
self.power=power_watt
return cur_clock
def report_energy(self):
self.set_power(self.power)
self.node.log("[PowerStates Plugin] Consumed "+str(self.energy) +"J")
def report_power_changes(self):
self.set_power(self.power)
for key in self.power_changes.keys():
self.node.log("[PowerStates Plugin] At t="+str(key)+" power is "+str(self.power_changes[key])+"W")
class PowerStatesFromFile(PowerStates):
"""
A version of Powerstates that load the power values from a file.
"""
def __init__(self,node,state_file,entry_line=1):
self.node=node
self.state_changes=dict()
self.states=[]
self.state=0
with open(state_file) as fp:
for i, line in enumerate(fp):
if i+1 == entry_line:
self.states=line.split(":")
self.states=[float(i) for i in self.states]
assert len(self.states) > 0
super().__init__(node,self.states[0])
self.set_state(0)
def set_state(self,state_id):
assert state_id < len(self.states)
clock=super().set_power(self.states[state_id])
if self.state != state_id:
self.state_changes[clock]=state_id
self.state=state_id
def report_state_changes(self):
self.set_state(self.state)
for key in self.state_changes.keys():
self.node.log("[PowerStates Plugin] At t="+str(key)+" state is "+str(self.state_changes[key]))
class PowerStatesComms(NodePlugin):
"""
Monitor the energy consumed by the network interfaces by mean of power states.
Note that for finer grained predictions, bytes and packet power consumption must be accounted.
Which is not the case with these power states.
"""
def __init__(self,api):
super().__init__("PowerStatesComms",api)
self.power=dict() # Store each interface informations
def on_communication_end(self,time,com_event):
content=com_event[2]
dataSize=content[4]
duration=time-content[7]
interface=content[2]
mode= "tx" if content[0] == self.api.node_id else "rx"
self.power[interface]["consumption_dynamic"]+=self.power[interface][mode]*duration
def set_power(self,interface,idle,tx,rx):
self.power[interface]=dict()
self.power[interface]["idle"]=idle
self.power[interface]["rx"]=rx
self.power[interface]["tx"]=tx
self.power[interface]["on_at"]=self.api.read("clock")
self.power[interface]["consumption_idle"]=0
self.power[interface]["consumption_dynamic"]=0
def on_turn_on(self):
for interface in self.power.keys():
self.power[interface]["on_at"]=self.api.read("clock")
def on_turn_off(self):
self.sync_idle()
def sync_idle(self):
clock=self.api.read("clock")
for interface in self.power.keys():
self.power[interface]["consumption_idle"]+=(clock-self.power[interface]["on_at"])*self.power[interface]["idle"]
self.power[interface]["on_at"]=clock
def get_energy(self):
self.sync_idle()
consumption=0
for interface in self.power.keys():
consumption+=self.power[interface]["consumption_idle"]+self.power[interface]["consumption_dynamic"]
return consumption
def report_energy(self):
self.log("Communications consumed "+str(round(self.get_energy(),2))+"J")
|