1: #!/usr/bin/env python
2:
3: import obd_io
4: import serial
5: import platform
6: import obd_sensors
7: from datetime import datetime
8: from PIL import Image,ImageDraw,ImageFont
9: import ImageOps
10: import nokiaSPI
11: import time
12: import os
13: import sqlite3
14: #from datetime import timedelta
15:
16: from obd_utils import scanSerial
17:
18: class OBD_Capture():
19: def __init__(self):
20: self.port = None
21: localtime = time.localtime(time.time())
22:
23: def connect(self):
24: portnames = scanSerial()
25: print portnames
26: for port in portnames:
27: self.port = obd_io.OBDPort(port, None, 2, 2)
28: if(self.port.State == 0):
29: self.port.close()
30: self.port = None
31: else:
32: break
33:
34: if(self.port):
35: print "Connected to "+self.port.port.name
36:
37: def is_connected(self):
38: return self.port
39:
40: def nokiprint(self,cShortTerm,cLongTerm,cLongTermMinutes):
41: cShortTerm = cShortTerm[:4]
42: cLongTerm = cLongTerm[:4]
43: noki.cls()
44: im = Image.new('1', (84,48))
45: draw = ImageDraw.Draw(im)
46: print cShortTerm
47: draw.text((0,0),cShortTerm, font=font, fill=1)
48: draw.text((0,24),cLongTerm, font=font, fill=1)
49: draw.text((54,7),"3 s", font=fontsmall, fill=1)
50: draw.text((54,31),cLongTermMinutes + " m", font=fontsmall, fill=1)
51: # Copy it to the display
52: noki.show_image(im)
53: #noki.next_row()
54:
55: def ComputeFuelConsumption(self):
56: nCurrentTime = time.time()
57:
58: try:
59: nStart = nCurrentTime - 20
60: cLimit = " and time_read > " + str(nStart) + " order by time_read desc limit 6"
61: cursor.execute('''SELECT maf,speed from SensorReadings where speed > "0" and maf > "0" and rpm != "NODATA" ''' + cLimit)
62: data = cursor.fetchall()
63: except sqlite3.OperationalError,msg:
64: return msg
65: #print len(data)
66: if (len(data) > 0):
67: nFuelConsumption = 0
68: for x in range(0,len(data)):
69: nFuelConsumption += (3600 * float(data[x][0]))/(9069.90 * float(data[x][1]))
70:
71: nAvgFuelConsumption = nFuelConsumption/len(data)
72: print nAvgFuelConsumption
73: print type(nAvgFuelConsumption)
74: #print data[x][0],data[x][1],data[x][2]
75: return "{:5.2f}".format(nAvgFuelConsumption).lstrip()
76: else:
77: return "No data"
78:
79: #print nAvgFuelConsum
80:
81: def is_number(self,DataToTest):
82: try:
83: float(DataToTest)
84: return True
85: except ValueError:
86: return False
87:
88:
89:
90:
91: def capture_data(self):
92: #Creating new database
93: for kounter in range(10000):
94: cKounter = "{0:05d}".format(kounter)
95: cNewDatabase = "obdii" + cKounter + ".db"
96: #print cNewDatabase
97: if not (os.path.exists(cNewDatabase)):
98: #print "New database name: " + cNewDatabase
99: break
100:
101: global conn
102: global cursor
103: conn = sqlite3.connect(cNewDatabase)
104: cursor = conn.cursor()
105:
106: #Find supported sensors - by getting PIDs from OBD
107: # its a string of binary 01010101010101
108: # 1 means the sensor is supported
109: self.supp = self.port.sensor(0)[1]
110: self.supportedSensorList = []
111: self.unsupportedSensorList = []
112:
113:
114: # loop through PIDs binary
115: for i in range(0, len(self.supp)):
116: if self.supp[i] == "1":
117: # store index of sensor and sensor object
118: self.supportedSensorList.append([i+1, obd_sensors.SENSORS[i+1]])
119: else:
120: self.unsupportedSensorList.append([i+1, obd_sensors.SENSORS[i+1]])
121:
122: sqlCreateTable = "CREATE TABLE SensorReadings (time_read real, "
123: sqlInsertTemplate = "INSERT INTO SensorReadings(time_read, "
124:
125: for supportedSensor in self.supportedSensorList:
126: #print "supported sensor index = " + str(supportedSensor[0]) + " " + str(supportedSensor[1].shortname)
127: sqlCreateTable += str(supportedSensor[1].shortname) + " text,"
128: sqlInsertTemplate += str(supportedSensor[1].shortname) + ","
129:
130: sqlCreateTable = sqlCreateTable[:sqlCreateTable.rfind(",")] + ")"
131: #print sqlCreateTable
132: try:
133: cursor.execute(sqlCreateTable)
134: conn.commit()
135: cursor.execute('''CREATE INDEX time_read_index on SensorReadings(time_read)''')
136: cMessage = "Database " + cNewDatabase + " created..."
137: except sqlite3.OperationalError,msg:
138: cMessage = msg
139: noki.cls()
140: noki.text(cMessage,wrap=True)
141:
142: sqlInsertTemplate = sqlInsertTemplate[:sqlInsertTemplate.rfind(",")] + ") VALUES ("
143: #print sqlInsertTemplate
144:
145: time.sleep(3)
146:
147: if(self.port is None):
148: return None
149:
150: #Loop until Ctrl C is pressed
151: try:
152: nRunningTotalFuelConsumption = 0
153: nStartTime = time.time()
154: x = 0
155: while True:
156: current_time = time.time()
157: #current_time = str(localtime.hour)+":"+str(localtime.minute)+":"+str(localtime.second)+"."+str(localtime.microsecond)
158: #log_string = current_time + "\n"
159: sqlInsert = sqlInsertTemplate + '"' + str(current_time) + '",'
160: results = {}
161: for supportedSensor in self.supportedSensorList:
162: sensorIndex = supportedSensor[0]
163: #print sensorIndex
164: (name, value, unit) = self.port.sensor(sensorIndex)
165: #log_string += name + " = " + str(value) + " " + str(unit) + "\n"
166: #print value,type(value)
167: sqlInsert += '"' + str(value) + '",'
168:
169:
170: sqlInsert = sqlInsert[:sqlInsert.rfind(",")] + ")"
171: #print sqlInsert
172:
173: try:
174: cursor.execute(sqlInsert)
175: conn.commit()
176: except sqlite3.OperationalError,msg:
177: noki.cls()
178: noki.text(msg,wrap=True)
179: continue
180:
181: cFuelConsumption = self.ComputeFuelConsumption()
182: if (cFuelConsumption != "No data"):
183: x += 1
184: if (x > 0):
185: if (self.is_number):
186: nRunningTotalFuelConsumption += float(cFuelConsumption)
187: nTripAverage = nRunningTotalFuelConsumption/x
188: cTripAverage = "{:5.2f}".format(nTripAverage).lstrip()
189: else:
190: cTripAverage = "Nodata"
191:
192: cDurationInMinutes = "{:3.0f}".format((current_time - nStartTime)/60).lstrip()
193: self.nokiprint(cFuelConsumption,cTripAverage,cDurationInMinutes)
194:
195: #print log_string,
196: #time.sleep(0.5)
197:
198:
199: except KeyboardInterrupt:
200: self.port.close()
201: print("stopped")
202:
203: if __name__ == "__main__":
204: font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf",26)
205: fontsmall = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 16)
206: # New b-w image
207: im = Image.new('1', (84,48))
208: noki = nokiaSPI.NokiaSPI(brightness=268) # create display device
209: noki.cls()
210: noki.text("Initializing..",wrap=True)
211:
212:
213: o = OBD_Capture()
214: o.connect()
215: time.sleep(3)
216: if not o.is_connected():
217: print "Not connected"
218: noki.cls()
219: noki.text("Error: Not connected to OBDII...",wrap=True)
220: time.sleep(10)
221: noki.set_brightness(0)
222: noki.cls()
223: exit()
224: else:
225: o.capture_data()