1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-04-12 04:40:03 +01:00

instrument: add conversion support to MeasurementType

- Change MeasurementType to derive from object rather than tuple.
- There is now support for conversion from one MeasurementType to
  another. A MeasurementType defines what it can be converted to and
  how.
This commit is contained in:
Sergei Trofimov 2017-06-06 14:15:40 +01:00
parent 8296d6c5d6
commit df81742100

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
from __future__ import division
import csv import csv
import logging import logging
import collections import collections
@ -24,28 +25,33 @@ from devlib.utils.types import numeric
INSTANTANEOUS = 1 INSTANTANEOUS = 1
CONTINUOUS = 2 CONTINUOUS = 2
MEASUREMENT_TYPES = {} # populated further down
class MeasurementType(tuple):
__slots__ = [] class MeasurementType(object):
def __new__(cls, name, units, category=None): def __init__(self, name, units, category=None, conversions=None):
return tuple.__new__(cls, (name, units, category)) self.name = name
self.units = units
self.category = category
self.conversions = {}
if conversions is not None:
for key, value in conversions.iteritems():
if not callable(value):
msg = 'Converter must be callable; got {} "{}"'
raise ValueError(msg.format(type(value), value))
self.conversions[key] = value
@property def convert(self, value, to):
def name(self): if isinstance(to, basestring) and to in MEASUREMENT_TYPES:
return tuple.__getitem__(self, 0) to = MEASUREMENT_TYPES[to]
if not isinstance(to, MeasurementType):
@property msg = 'Unexpected conversion target: "{}"'
def units(self): raise ValueError(msg.format(to))
return tuple.__getitem__(self, 1) if not to.name in self.conversions:
msg = 'No conversion from {} to {} available'
@property raise ValueError(msg.format(self.name, to.name))
def category(self): return self.conversions[to.name](value)
return tuple.__getitem__(self, 2)
def __getitem__(self, item):
raise TypeError()
def __cmp__(self, other): def __cmp__(self, other):
if isinstance(other, MeasurementType): if isinstance(other, MeasurementType):
@ -55,7 +61,13 @@ class MeasurementType(tuple):
def __str__(self): def __str__(self):
return self.name return self.name
__repr__ = __str__ def __repr__(self):
if self.category:
text = 'MeasurementType({}, {}, {})'
return text.format(self.name, self.units, self.category)
else:
text = 'MeasurementType({}, {})'
return text.format(self.name, self.units)
# Standard measures # Standard measures
@ -72,7 +84,8 @@ _measurement_types = [
MeasurementType('rx', 'bytes', 'data transfer'), MeasurementType('rx', 'bytes', 'data transfer'),
MeasurementType('tx/rx', 'bytes', 'data transfer'), MeasurementType('tx/rx', 'bytes', 'data transfer'),
] ]
MEASUREMENT_TYPES = {m.name: m for m in _measurement_types} for m in _measurement_types:
MEASUREMENT_TYPES[m.name] = m
class Measurement(object): class Measurement(object):