Coverage for d7a/types/ct.py: 94%

36 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-05-24 08:03 +0200

1# 

2# Copyright (c) 2015-2021 University of Antwerp, Aloxy NV. 

3# 

4# This file is part of pyd7a. 

5# See https://github.com/Sub-IoT/pyd7a for further info. 

6# 

7# Licensed under the Apache License, Version 2.0 (the "License"); 

8# you may not use this file except in compliance with the License. 

9# You may obtain a copy of the License at 

10# 

11# http://www.apache.org/licenses/LICENSE-2.0 

12# 

13# Unless required by applicable law or agreed to in writing, software 

14# distributed under the License is distributed on an "AS IS" BASIS, 

15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

16# See the License for the specific language governing permissions and 

17# limitations under the License. 

18# 

19 

20# author: Christophe VG <contact@christophe.vg> 

21# class for representing compressed time 

22 

23# The compressed time format allows compressing to 1 byte a time duration ranged 

24# from 0 to 507904 Ti (0 to 496 s) with variable Ti resolution. It can be  

25# converted to Ti using the following formula: T = (4^EXP)x(MANT) Ti 

26 

27import math 

28 

29from cerberus import Validator 

30 

31# Compressed Time 

32# 

33# b7-b5 EXP Exponent (ranging from 0 to 7) 

34# b4-b0 MANT Mantissa (ranging from 0 to 31) 

35 

36from d7a.support.schema import Validatable 

37 

38class CT(Validatable): 

39 

40 SCHEMA = [{ 

41 "exp" : { "type": "integer", "min" : 0, "max": 7 }, 

42 "mant" : { "type": "integer", "min" : 0, "max": 31 } 

43 }] 

44 

45 def __init__(self, exp=0, mant=0): 

46 self.exp = exp 

47 self.mant = mant 

48 super(CT, self).__init__() 

49 

50 def __int__(self): 

51 return int(math.pow(4, self.exp) * self.mant) 

52 

53 def __iter__(self): 

54 yield self.compressed_value() 

55 

56 def compressed_value(self): 

57 byte = 0 

58 byte |= self.exp << 5 

59 byte += self.mant 

60 return byte 

61 

62 @staticmethod 

63 def parse(s): 

64 exp = s.read("uint:3") 

65 mant = s.read("uint:5") 

66 return CT(exp=exp, mant=mant) 

67 

68 @staticmethod 

69 def compress(value, ceil=True): 

70 for i in range(8): 

71 if(value <= math.pow(4, i) * 31): 

72 mantissa = int(value / math.pow(4, i)) 

73 remainder = value % math.pow(4, i) 

74 

75 if(ceil and remainder): 

76 mantissa = mantissa + 1 

77 return CT(i, mantissa) 

78 

79 def decompress(self): 

80 return int(math.pow(4, (self.compressed_value() >> 5))) * (self.compressed_value() & 0b11111) 

81 

82 def __str__(self): 

83 return "exp={} mant{}".format(self.exp, self.mant)