forked from iot-lab/cli-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
profile.py
198 lines (160 loc) · 6.75 KB
/
profile.py
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# -*- coding:utf-8 -*-
# This file is a part of IoT-LAB cli-tools
# Copyright (C) 2015 INRIA (Contact: admin@iot-lab.info)
# Contributor(s) : see AUTHORS file
#
# This software is governed by the CeCILL license under French law
# and abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# http://www.cecill.info.
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
"""Class python for Profile serialization JSON"""
# pylint:disable=too-few-public-methods
class ProfileM3A8(object):
"""A generic Profile for M3 and A8 """
choices = {
'power_mode': ['dc', 'battery'],
'consumption': {'period': [140, 204, 332, 588, 1100, 2116, 4156, 8244],
'average': [1, 4, 16, 64, 128, 256, 512, 1024]},
'radio': {'channels': range(11, 27), 'num_per_channel': range(0, 256),
'period': range(1, 2**16)}
}
arch = None
def __init__(self, profilename, power):
assert power in self.choices['power_mode']
assert self.arch is not None, "Using Generic class"
self.nodearch = self.arch
self.profilename = profilename
self.power = power
self.consumption = None
self.radio = None
# pylint: disable=too-many-arguments
def set_consumption(self, period, average,
power=False, voltage=False, current=False):
""" Configure consumption measures """
if not power and not voltage and not current:
return
_err = "Required values period/average for consumption measure."
assert period is not None and average is not None, _err
assert period in self.choices['consumption']['period']
assert average in self.choices['consumption']['average']
self.consumption = {
'period': period,
'average': average,
'power': power,
'voltage': voltage,
'current': current,
}
def set_radio(self, mode, channels, period=None, num_per_channel=None):
""" Configure radio measures """
if not mode:
return
assert len(channels)
for channel in channels:
assert channel in self.choices['radio']['channels']
assert mode in ['rssi', 'sniffer']
self.radio = {
'mode': mode
}
config_radio = {
'rssi': self._cfg_radio_rssi,
'sniffer': self._cfg_radio_sniffer
}
config_radio[mode](channels, period, num_per_channel)
def _cfg_radio_rssi(self, channels, period, num_per_channel=None):
""" Check parameters for rssi measures and set config """
num_per_channel = num_per_channel or 0
_err = "Required 'channels/period' for radio rssi measure"
assert period is not None and channels is not None, _err
# num_per_channel is required when multiple channels are given
_err = "Required 'num_per_channel' as multiple channels provided"
assert len(channels) == 1 or num_per_channel != 0, _err
assert period in self.choices['radio']['period']
assert num_per_channel in self.choices['radio']['num_per_channel']
# Write usefull parameters
self.radio['channels'] = channels
self.radio['period'] = period
self.radio['num_per_channel'] = num_per_channel
def _cfg_radio_sniffer(self, channels, period=None, num_per_channel=None):
""" Check parameters for sniffer measures and set the configuration """
# 'Period' and multiple channels should be handled later when supported
_err = "`period` and `num_per_channel` not allowed for sniffer"
assert period is None and num_per_channel is None, _err
assert len(channels) == 1, "Only one channel is allowed"
# Write config
self.radio['channels'] = channels
self.radio['period'] = None
self.radio['num_per_channel'] = None
def __eq__(self, other): # pragma: no cover
return self.__dict__ == other.__dict__
class ProfileM3(ProfileM3A8):
"""A Profile measure class for M3."""
arch = 'm3'
class ProfileA8(ProfileM3A8):
"""A Profile measure class for A8."""
arch = 'a8'
class ProfileCustom(ProfileM3A8):
"""A Profile measure class for Custom."""
arch = 'custom'
class ProfileWSN430(object):
"""A Profile measure class for WSN430 """
choices = {
'power_mode': ['dc', 'battery'],
'consumption': {'frequency': [5000, 1000, 500, 100, 70]},
'radio': {'frequency': [5000, 1000, 500]},
'sensor': {'frequency': [30000, 10000, 5000, 1000]},
}
def __init__(self, profilename, power):
assert power in ProfileWSN430.choices['power_mode']
self.nodearch = 'wsn430'
self.profilename = profilename
self.power = power
self.consumption = None
self.radio = None
self.sensor = None
def set_consumption(self, frequency, power=False, voltage=False,
current=False):
""" Configure consumption measures """
if not power and not voltage and not current:
return
_err = "Required 'frequency' for consumption measure"
assert frequency is not None, _err
assert frequency in self.choices['consumption']['frequency']
self.consumption = {
'frequency': frequency,
'power': power,
'voltage': voltage,
'current': current,
}
def set_radio(self, frequency):
""" Configure radio measures """
if not frequency:
return
assert frequency in self.choices['radio']['frequency']
self.radio = {
'frequency': frequency,
'rssi': True,
}
def set_sensors(self, frequency, temperature=False, luminosity=False):
""" Configure sensor measures """
if not temperature and not luminosity:
return
_err = "Required 'frequency' for sensor measure"
assert frequency is not None, _err
assert frequency in self.choices['sensor']['frequency']
self.sensor = {
'frequency': frequency,
'luminosity': luminosity,
'temperature': temperature,
}
def __eq__(self, other): # pragma: no cover
return self.__dict__ == other.__dict__