Don't use eval for converting strings
[pyobd] / obd_sensors.py
1  #!/usr/bin/env python
2 ###########################################################################
3 # obd_sensors.py
4 #
5 # Copyright 2004 Donour Sizemore (donour@uchicago.edu)
6 # Copyright 2009 Secons Ltd. (www.obdtester.com)
7 #
8 # This file is part of pyOBD.
9 #
10 # pyOBD is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # pyOBD is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with pyOBD; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 ###########################################################################
24
25 def hex_to_int(str):
26     i = eval("0x" + str, {}, {})
27     return i
28
29 def maf(code):
30     code = hex_to_int(code)
31     return code * 0.00132276
32
33 def throttle_pos(code):
34     code = hex_to_int(code)
35     return code * 100.0 / 255.0
36
37 def intake_m_pres(code): # in kPa
38     code = hex_to_int(code)
39     return code / 0.14504
40     
41 def rpm(code):
42     code = hex_to_int(code)
43     return code / 4
44
45 def speed(code):
46     code = hex_to_int(code)
47     return code / 1.609
48
49 def percent_scale(code):
50     code = hex_to_int(code)
51     return code * 100.0 / 255.0
52
53 def timing_advance(code):
54     code = hex_to_int(code)
55     return (code - 128) / 2.0
56
57 def sec_to_min(code):
58     code = hex_to_int(code)
59     return code / 60
60
61 def temp(code):
62     code = hex_to_int(code)
63     return code - 40 
64
65 def cpass(code):
66     #fixme
67     return code
68
69 def fuel_trim_percent(code):
70     code = hex_to_int(code)
71     return (code - 128.0) * 100.0 / 128
72
73 def dtc_decrypt(code):
74     #first byte is byte after PID and without spaces
75     num = hex_to_int(code[:2]) #A byte
76     res = []
77
78     if num & 0x80: # is mil light on
79         mil = 1
80     else:
81         mil = 0
82         
83     # bit 0-6 are the number of dtc's. 
84     num = num & 0x7f
85     
86     res.append(num)
87     res.append(mil)
88     
89     numB = hex_to_int(code[2:4]) #B byte
90       
91     for i in range(0,3):
92         res.append(((numB>>i)&0x01)+((numB>>(3+i))&0x02))
93     
94     numC = hex_to_int(code[4:6]) #C byte
95     numD = hex_to_int(code[6:8]) #D byte
96        
97     for i in range(0,7):
98         res.append(((numC>>i)&0x01)+(((numD>>i)&0x01)<<1))
99     
100     res.append(((numD>>7)&0x01)) #EGR SystemC7  bit of different 
101     
102     return res
103
104 def bin(s):
105     return str(s) if s<=1 else bin(s>>1) + str(s&1)
106
107 def hex_to_bitstring(str):
108     return bin(int(str, 16))
109
110 class Sensor:
111     def __init__(self,sensorName, sensorcommand, sensorValueFunction, u):
112         self.name = sensorName
113         self.cmd  = sensorcommand
114         self.value= sensorValueFunction
115         self.unit = u
116
117 SENSORS = [
118     Sensor("          Supported PIDs", "0100", hex_to_bitstring  ,""       ),    
119     Sensor("Status Since DTC Cleared", "0101", dtc_decrypt       ,""       ),    
120     Sensor("DTC Causing Freeze Frame", "0102", cpass             ,""       ),    
121     Sensor("      Fuel System Status", "0103", cpass             ,""       ),
122     Sensor("   Calculated Load Value", "0104", percent_scale     ,""       ),    
123     Sensor("     Coolant Temperature", "0105", temp              ,"C"      ),
124     Sensor("    Short Term Fuel Trim", "0106", fuel_trim_percent ,"%"      ),
125     Sensor("     Long Term Fuel Trim", "0107", fuel_trim_percent ,"%"      ),
126     Sensor("    Short Term Fuel Trim", "0108", fuel_trim_percent ,"%"      ),
127     Sensor("     Long Term Fuel Trim", "0109", fuel_trim_percent ,"%"      ),
128     Sensor("      Fuel Rail Pressure", "010A", cpass             ,""       ),
129     Sensor("Intake Manifold Pressure", "010B", intake_m_pres     ,"psi"    ),
130     Sensor("              Engine RPM", "010C", rpm               ,""       ),
131     Sensor("           Vehicle Speed", "010D", speed             ,"MPH"    ),
132     Sensor("          Timing Advance", "010E", timing_advance    ,"degrees"),
133     Sensor("         Intake Air Temp", "010F", temp              ,"C"      ),
134     Sensor("     Air Flow Rate (MAF)", "0110", maf               ,"lb/min" ),
135     Sensor("       Throttle Position", "0111", throttle_pos      ,"%"      ),
136     Sensor("    Secondary Air Status", "0112", cpass             ,""       ),
137     Sensor("  Location of O2 sensors", "0113", cpass             ,""       ),
138     Sensor("        O2 Sensor: 1 - 1", "0114", fuel_trim_percent ,"%"      ),
139     Sensor("        O2 Sensor: 1 - 2", "0115", fuel_trim_percent ,"%"      ),
140     Sensor("        O2 Sensor: 1 - 3", "0116", fuel_trim_percent ,"%"      ),
141     Sensor("        O2 Sensor: 1 - 4", "0117", fuel_trim_percent ,"%"      ),
142     Sensor("        O2 Sensor: 2 - 1", "0118", fuel_trim_percent ,"%"      ),
143     Sensor("        O2 Sensor: 2 - 2", "0119", fuel_trim_percent ,"%"      ),
144     Sensor("        O2 Sensor: 2 - 3", "011A", fuel_trim_percent ,"%"      ),
145     Sensor("        O2 Sensor: 2 - 4", "011B", fuel_trim_percent ,"%"      ),
146     Sensor("         OBD Designation", "011C", cpass             ,""       ),
147     Sensor("  Location of O2 sensors", "011D", cpass             ,""       ),
148     Sensor("        Aux input status", "011E", cpass             ,""       ),
149     Sensor(" Time Since Engine Start", "011F", sec_to_min        ,"min"    ),
150     Sensor("  Engine Run with MIL on", "014E", sec_to_min        ,"min"    ),
151
152     ]
153      
154     
155 #___________________________________________________________
156
157 def test():
158     for i in SENSORS:
159         print i.name, i.value("F")
160
161 if __name__ == "__main__":
162     test()