EPC decoding module.

This commit is contained in:
Mikaël Ates 2016-03-09 15:27:26 +01:00
parent 792ea0a28a
commit eb31e87f20
2 changed files with 206 additions and 0 deletions

0
__init__.py Normal file
View File

206
epc.py Normal file
View File

@ -0,0 +1,206 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Copyright (C) 2016 Entr'ouvert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import sys
import re
class InvalidEPC(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def word_flag(word):
'''
Test first bit of a 2 bytes words.
'''
return word & 32768
class VeadistaEPC:
def __init__(self, epc,
trcal=85e-6, # V
can_precision=13e-3, # V
sensor_sensibility=70e-3, # V/°C
sensor_center=34): # °C at 011111(b) = 31(d)
if len(epc) != 24 or not re.match(r'[0-9a-fA-F]{24}', epc):
raise InvalidEPC(epc)
self.epc = epc
self.words = [int(self.epc[i*4: i*4+4], 16) for i in range(6)]
self.trcal = trcal
self.can_precision = can_precision
self.sensor_sensibility = sensor_sensibility
self.sensor_center = sensor_center
self.can_step = can_precision / sensor_sensibility
self.sensor_start = sensor_center - 31 * self.can_step
(self.temperature_int,
self.temperature_degree,
self.temperature_volt) = self.get_temperature()
(self.tension_int,
self.tension_volt) = self.get_tension()
(self.cpt_trcal,
self.period_osc,
((self.hr1_int,
self.hr1_second,
self.hr1_bpm),
(self.hr2_int,
self.hr2_second,
self.hr2_bpm),
(self.hr3_int,
self.hr3_second,
self.hr3_bpm))) = self.get_hr()
def t_celsius(self, value):
return self.sensor_start + value * self.can_step
def t_voltage(self, value):
return value * self.can_precision
def get_temperature(self):
w = self.words[1]
value = w & 63 # 6 lsb
if word_flag(w):
return value, self.t_celsius(value), self.t_voltage(value)
return None, None, None
def get_tension(self):
w = self.words[2]
value = w & 63 # 6 lsb
if word_flag(w):
return value, self.t_voltage(value)
return None, None
def get_hr(self):
w = self.words[3]
raw_trcal_count = w & 32512
if raw_trcal_count:
cpt_trcal = raw_trcal_count >> 8
period_osc = self.trcal / (4 * (cpt_trcal + 1))
def process_hr(w):
if word_flag(w):
count = w & 255
if count > 2:
period = (count + 1) * 4 * 4096 * period_osc
return count, period, 60 / period
return None, None, None
return (cpt_trcal,
period_osc,
[process_hr(self.words[3+i]) for i in range(3)])
return None, None, None
def __str__(self):
string = "----------------------------------------------------------------------"
string += "\nEPC:\t{}\n".format(' '.join([self.epc[i*4:i*4+4] for i in range(6)]))
w = self.words[1]
string += "\nWord 3:\t\t\thex : {}\tint : {}\tbin : {:b}\n".format(self.epc[4:8], w, w)
value = w & 63
if word_flag(w):
string += "CAN precision :\t\t{}V\n".format(self.can_precision)
string += "Sensor sensibility :\t{}V/°C\n".format(self.sensor_sensibility)
string += "Sensor centered at :\t{}°C\n".format(self.sensor_center)
string += "Sensor range :"
string += "\t\t{}°C to {}°C\n".format(self.sensor_start,
self.sensor_start + 63 * self.can_step)
string += "Temperature :\t\tint : {0}/63\tbin : {0:b}\n".format(self.temperature_int)
string += "Temperature :\t\t{} V\n".format(self.temperature_volt)
string += "Temperature :\t\t{} °C\n".format(self.temperature_degree)
else:
string += "Temperature :\t\tflag is null.\n"
w = self.words[2]
string += "\nWord 4:\t\t\thex : {}\tint : {}\tbin : {:b}\n".format(self.epc[8:12], w, w)
value = w & 63
if word_flag(w):
string += "CAN precision :\t\t{}mV\n".format(self.can_precision)
string += "External voltage :\tint : {0}/63\tbin : {0:b}\n".format(self.tension_int)
string += "External voltage :\t{} V\n".format(self.tension_volt)
else:
string += "External voltage :\tflag is null.\n"
w = self.words[3]
string += "\nWord 5:\t\t\thex : {}\tint : {}\tbin : {:b}\n".format(self.epc[12:16], w, w)
raw_trcal_count = w & 32512
if not raw_trcal_count:
string += "No TRCAL count\n"
else:
count = raw_trcal_count >> 8
string += "TRCAL reader set : \t{}s\n".format(self.trcal)
string += "TRCAL count : \t\tint : {0}/127\tbin : {0:b}\n".format(self.cpt_trcal)
string += "Osc period (s) : \t{}\n".format(self.period_osc)
string += "Osc frequency (Hz) : \t{}\n".format(1/self.period_osc)
def process_hr(number, word, value, second, bpm):
string = ""
if word_flag(word):
if not value:
string += "Interval {} :\t\tno value\n".format(number)
elif value <= 2:
string += "Interval {} :\t\tthe sensor".format(number)
string += "seems to be pressed continuously."
string += "\traw int: {0}/255\traw bin : {0:b}\n".format(value)
else:
string += "Interval {0} :\t\tint: {1}/255".format(number, value)
string += "\traw bin : {:b}\n".format(value)
string += "Interval {} :\t\t{} s\n".format(number, second)
string += "Interval {} :\t\t{} bpm\n".format(number, bpm)
else:
string += "Interval {} :\t\tflag is null.\n".format(number)
return string
string += process_hr(1, w, self.hr1_int, self.hr1_second, self.hr1_bpm)
w = self.words[4]
string += "\nWord 6:\t\t\thex : {}".format(self.epc[16:20])
string += "\tint : {0}\tbin : {0:b}\n".format(w)
string += process_hr(2, w, self.hr2_int, self.hr2_second, self.hr2_bpm)
w = self.words[5]
string += "\nWord 7:\t\t\thex : {}".format(self.epc[20:24])
string += "\tint : {0}\tbin : {0:b}\n".format(w)
string += process_hr(3, w, self.hr3_int, self.hr3_second, self.hr3_bpm)
string += "----------------------------------------------------------------------\n"
return string
if __name__ == "__main__":
epc = "FFFF800D8009A17C807C0000"
if len(sys.argv) > 1:
epc = sys.argv[1]
epc = VeadistaEPC(epc)
print(epc)