def test_createRandomDataFileNoGPS(self): log = LogFile() log.createLogfile("Random_NoGPS.test") time = range(100) speed = np.random.randint(100, size=100).tolist() rpm = np.random.randint(5000, size=100).tolist() load = np.random.randint(100, size=100).tolist() maf = np.random.randint(100, size=100).tolist() temp = np.random.randint(30, size=100).tolist() pedal = np.random.randint(100, size=100).tolist() afr = [1] * 100 fuel_lvl = np.random.randint(100, size=100).tolist() gps_long = [None] * 100 gps_lat = [None] * 100 gps_alt = [None] * 100 gps_time = [None] * 100 internal_temp = np.random.randint(30, size=100).tolist() vin = ["MF0DXXGAKDJP09111"] * 100 for i in range(0, len(speed)): log.addData([ time[i], speed[i], rpm[i], load[i], maf[i], temp[i], pedal[i], afr[i], fuel_lvl[i], gps_long[i], gps_lat[i], gps_alt[i], gps_time[i], internal_temp[i], vin[i] ]) log.appendFile() log2 = LogFile() log2.loadFromFile(log.getfilename()) speed_csv = log2.getLabelData(signals.SPEED.name) afr_csv = log2.getLabelData(signals.COMMANDED_EQUIV_RATIO.name) temp_csv = log2.getLabelData(signals.AMBIANT_AIR_TEMP.name) rpm_csv = log2.getLabelData(signals.RPM.name) load_csv = log2.getLabelData(signals.ENGINE_LOAD.name) maf_csv = log2.getLabelData(signals.MAF.name) pedal_csv = log2.getLabelData(signals.RELATIVE_ACCEL_POS.name) fuel_lvl_csv = log2.getLabelData(signals.FUEL_LEVEL.name) gps_long_csv = log2.getLabelData(signals.GPS_Long.name) gps_lat_csv = log2.getLabelData(signals.GPS_Lat.name) gps_alt_csv = log2.getLabelData(signals.GPS_Alt.name) gps_time_csv = log2.getLabelData(signals.GPS_Time.name) internal_temp_csv = log2.getLabelData(signals.INTERNAL_AIR_TEMP.name) vin_csv = log2.getLabelData(signals.VIN.name) self.assertTrue(log2.isBrokenFile()) self.assertEqual(speed_csv, speed) self.assertEqual(afr_csv, afr) self.assertEqual(temp_csv, temp) self.assertEqual(rpm_csv, rpm) self.assertEqual(load_csv, load) self.assertEqual(maf_csv, maf) self.assertEqual(pedal_csv, pedal) self.assertEqual(fuel_lvl_csv, fuel_lvl) self.assertEqual(gps_long_csv, gps_long) self.assertEqual(gps_lat_csv, gps_lat) self.assertEqual(gps_alt_csv, gps_alt) self.assertEqual(gps_time_csv, gps_time) self.assertEqual(internal_temp_csv, internal_temp) self.assertEqual(vin_csv, vin) self.assertEqual(log2._VIN, "MF0DXXGAKDJP09111")
def test_createZerosDataFile(self): log = LogFile() log.createLogfile("Zeros.test") time = range(100) speed = [0] * 100 rpm = [0] * 100 load = [0] * 100 maf = [0] * 100 temp = [0] * 100 pedal = [0] * 100 afr = [0] * 100 fuel_lvl = [None] * 100 gps_long = [None] * 100 gps_lat = [None] * 100 gps_alt = [None] * 100 gps_time = [None] * 100 internal_temp = [None] * 100 vin = ["VIN12FBASSF13"] * 100 for i in range(0, len(speed)): log.addData([ time[i], speed[i], rpm[i], load[i], maf[i], temp[i], pedal[i], afr[i], fuel_lvl[i], gps_long[i], gps_lat[i], gps_alt[i], gps_time[i], internal_temp[i], vin[i] ]) log.appendFile() log2 = LogFile() log2.loadFromFile(log.getfilename()) speed_csv = log2.getLabelData(signals.SPEED.name) afr_csv = log2.getLabelData(signals.COMMANDED_EQUIV_RATIO.name) temp_csv = log2.getLabelData(signals.AMBIANT_AIR_TEMP.name) rpm_csv = log2.getLabelData(signals.RPM.name) load_csv = log2.getLabelData(signals.ENGINE_LOAD.name) maf_csv = log2.getLabelData(signals.MAF.name) pedal_csv = log2.getLabelData(signals.RELATIVE_ACCEL_POS.name) fuel_lvl_csv = log2.getLabelData(signals.FUEL_LEVEL.name) gps_long_csv = log2.getLabelData(signals.GPS_Long.name) gps_lat_csv = log2.getLabelData(signals.GPS_Lat.name) gps_alt_csv = log2.getLabelData(signals.GPS_Alt.name) gps_time_csv = log2.getLabelData(signals.GPS_Time.name) internal_temp_csv = log2.getLabelData(signals.INTERNAL_AIR_TEMP.name) vin_csv = log2.getLabelData(signals.VIN.name) self.assertTrue(log2.isBrokenFile()) self.assertEqual(speed_csv, speed) self.assertEqual(afr_csv, afr) self.assertEqual(temp_csv, temp) self.assertEqual(rpm_csv, rpm) self.assertEqual(load_csv, load) self.assertEqual(maf_csv, maf) self.assertEqual(pedal_csv, pedal) self.assertEqual(fuel_lvl_csv, fuel_lvl) self.assertEqual(gps_long_csv, gps_long) self.assertEqual(gps_lat_csv, gps_lat) self.assertEqual(gps_alt_csv, gps_alt) self.assertEqual(gps_time_csv, gps_time) self.assertEqual(internal_temp_csv, internal_temp) self.assertEqual(vin_csv, vin)
def main(): """ Main function to execute the datalogging process. When the script gets executed, this function will be executed. """ ### GPIO configuration # BCM numeration for the GPIOs GPIO.setmode(GPIO.BCM) # Configure the GPIOs as outputs GPIO.setup(17, GPIO.OUT) GPIO.setup(27, GPIO.OUT) GPIO.setup(22, GPIO.OUT) # No warnings GPIO.setwarnings(False) # Define variables for the GPIOs representing the color for the RGB RGBblue = 17 RGBred = 27 RGBgreen = 22 # Set the RGB to white light (all colors) GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) GPIO.output(RGBred, GPIO.HIGH) GPIO.output(RGBgreen, GPIO.HIGH) ### Create threads (GPS & temperature) # Create an instance of the GpsPoller and start the thread for its polling gpsp = GpsPoller() gpsp.start() # Create an instance of the TempPoller and start the thread for its polling temperature = TempPoller() temperature.start() ### Necessary variables initialization # Line counter. Is necessary to manage the different sample rates of the # different signals i = 0 # No connection yet connection = None NotConnected = True # Error count to detect the moment when ignition is turned off at the end # of a Driving Cycle errorcnt = 0 wait_gps_count = 0 HasConnection = True # Not only GPS logging (yet) --> emergeny mode if no connection to the OBD OnlyGPSMode = 0 # No OBD errors yet OBDError = 0 # Create a CSV file name with the date, time and suffix "test" filename = datetime.datetime.now().strftime( "%y_%m_%d_%H:%M:%S_") + "test.csv" # Get the time how long the system is on start = uptime() ### Set up OBD connection # Try to establish a connection with the OBD dongle while NotConnected: if OBDError % 2 == 1: GPIO.output(RGBgreen, GPIO.HIGH) else: GPIO.output(RGBgreen, GPIO.LOW) try: # Connect to OBD dongle print("creating OBD object") connection = obd.OBD() # Try to connect to OBD dongle print("retrieving OBD status") print(connection.status()) # Print OBD Status for debugging # If the return of query RPM signal is not null # --> Connecting succeeded if (connection.status() == obd.utils.OBDStatus.CAR_CONNECTED and (connection.query(obd.commands.RPM).is_null() == False)): NotConnected = False print("Successful connected to OBDII!" ) # Connecting to OBD dongle succeeded time.sleep(1) # Connection not successful: Sleep 1s before trying to connect to OBD dongle again else: time.sleep(1) # Cannot connect to the OBD: wait, add an OBD error and try again except Exception as e: print("Exception : ", e) print("Error Connecting to OBD-Adapter (" + str(OBDError) + ")") time.sleep(1) OBDError += 1 # If could not connect to the OBD for the tenth time, use the only GPS # mode to log only the GPS and temperature signal if OBDError == 5: NotConnected = False OnlyGPSMode = 1 print("running in OnlyGPSMode now") ### pid01_1, pid01_2, pid01_3, pid01_4, pid01_5, pid01_6, pid09 = obd_find_signals( ) with open('setup.json') as json_file: setup = json.load(json_file) obd_signals = setup("obd_signals") # concatenate signals, format to binary available_signals = {} for key in obd_signals.keys(): available_signals[key] = check_signal( obd_signals.get(key), pid01_1 + pid01_2 + pid01_3 + pid01_4 + pid01_5 + pid01_6 + pid09) ### Creation LogFile object and variables # Create an object of LogFile log = LogFile() # Reset the OBD errors to 0 OBDError = 0 # Mode has been stated, need to start only GPS mode or normal mode temp = True # Prefix and suffix for the logfile that will be created, to difference # between a file for the normal or the only GPS mode stri = "" stri_end = ".keep" ### Handling onlyGpsMode # Handle only GPS Mode: check if GPS data available (until connection works) while temp and OnlyGPSMode == 1 and wait_gps_count <= 20: if wait_gps_count % 2 == 1: GPIO.output(RGBred, GPIO.LOW) else: GPIO.output(RGBred, GPIO.HIGH) # Get the current value from the GPS report = gpsp.get_current_value() wait_gps_count += 1 print("Report: ", report) ### Check for GPS connection # If the JSON objecthas the right class, there is a GPS connection if report['class'] == 'TPV': # If the longitude, latitude and altitude are existing, the # connection was successful if hasattr(report, 'lon') and hasattr(report, 'lat') and hasattr( report, 'alt'): print("GPS found-> Only GPS Mode") # Set Colour to Cyan GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) # Set the prefix and suffix to mark the CSV file for only GPS stri = "GPS_" stri_end = "x" # Set that the only GPS mode can be executed OnlyGPSMode = 2 temp = False # Not able to connect: Wait a second and try again else: time.sleep(1) ### Creation logfile # Create a logfile log.createLogfile(stri + filename + stri_end) # No VIN yet vin = 12345 # Get the time how long the system is on start = uptime() ### Perform datalogging try: ### Execute onlyGpsMode while OnlyGPSMode == 2: # Line counter for control of sample rates i = i + 1 # If the counter is too big (--> StopIteration): reset if i == 2048: i = 0 # Execute the function for the only GPS mode GPS_Only(log, i, start, temperature, gpsp) ### Execute normal mode ### Set up normal mode # If OBD is successfully connected: Set the normal mode up if connection is not None and connection.status( ) == obd.utils.OBDStatus.CAR_CONNECTED and HasConnection: print("Trying to get RPM") if available_signals.get("RPM") == 1: response = connection.query(obd.commands.RPM) print("RPM query response: ", response) else: print("RPM is not an available signal on this vehicle") # Trying to get Vehicle Identification Number if the signal is not available assign 1234 print("Trying to get VIN") if available_signals["VIN"] == 1: c = OBDCommand("VIN", "Get Vehicle Identification Number", b"0902", 20, raw_string, ECU.ENGINE, False) response = connection.query(c, force=True) vin = LogFile.parseVIN(response.value) print("VIN: ", vin) else: print("Vin is not an available signal on this vehicle") vin = 1234 # connection.close() # Change to asynchronous connection: last value always immediatly # retrievable connection = obd.Async() # Keep track of the RPM (constantly get its value) connection.watch(obd.commands.RPM) # Keep track of every defined OBD signal for signal in signals.getOBDSignalList(): print("watching ", signal.name) connection.watch(obd.commands[signal.name]) # Start the update loop of the OBD values connection.start() # Wait a moment time.sleep(0.5) # Set RGB colour to pink GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) GPIO.output(RGBred, GPIO.HIGH) ### Perform normal mode # Normal Mode: OBD-, GPS-, Temperature-Data while connection is not None and connection.status( ) == obd.utils.OBDStatus.CAR_CONNECTED and HasConnection: ### Ignition off? # Error handling to detect IGNITION OFF Signal (RPM is 0 then) if available_signals["RPM"] == 1: if connection.query(obd.commands.RPM).is_null() is True: print("Error") errorcnt += 1 print(errorcnt) # If RPM is not 0, reset the errors (just a disruption) else: errorcnt = 0 # If the fifth error occured,most likely the ignition is off if errorcnt >= 5: print("End: Too many Errors - Ignition seems to be off") # No connection anymore HasConnection = False # Turn off the RGB GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) ### Signal recording # Increment the line counter for the control of the sample rates i = i + 1 # If counter is too big, reset becuase of StopIteration if i == 2048: i = 0 # Get actual time data # timestr = str(datetime.datetime.now()) # Get the time how long the system is on timestr = uptime() # Calculate the time since the start of measurement timestr = timestr - start # Create a list to for the signal values result = [timestr] # Append the calculated time # Set the GPS and Temperature variables to initial values (for the # case that no value is recorded) lon = None lat = None gpsTime = None internalTemp = None alt = None # Get GPS data (if possible) if i % signals.getSignal("GPS_Long").sampleRate == 0: report = gpsp.get_current_value() (lon, lat, alt, gpsTime) = getGpsData(report) # Get internal tempterature data if i % signals.getSignal("INTERNAL_AIR_TEMP").sampleRate == 0: internalTemp = temperature.get_current_value() # Get OBD data for every defined OBD signal for signal in signals.getOBDSignalList(): # Handle the different sample times (with counter i) if i % signal.sampleRate == 0: r = connection.query(obd.commands[signal.name]) # If the response is null, append a 0 as value, else the # returned value if r.is_null(): result.append(0) else: result.append(r.value.magnitude) # If no sample for this time, append None else: result.append(None) # Append GPS-Data (if available) result.append(lon) result.append(lat) result.append(alt) result.append(gpsTime) # Append Temperature-Data (if available) result.append(internalTemp) result.append(vin) ### Recorded data to buffer # Append the list of values to the buffer (dictionary of the # signals with a list of its values as value) log.addData(result) # Write the VIN only once --> does not change and reduce data amount if vin is not None: vin = None # Wait a moment to limit the data amount time.sleep(0.5) ### Buffer to file # Every 20 rows of measurement: append the buffer data to the CSV file if i % 20 == 0: log.appendFile() print("Appending File ...") ### Ignition is off # Append the buffer data to the CSV file log.appendFile() print("Ignition Off") print("\nKilling Threads..") ### End threads # End the GPS polling thread gpsp.running = False gpsp.join() # End the temperature polling thread temperature.running = False temperature.join() ### Disconnect OBD # Stop the connection to the OBD connection.stop() ### Configure GPIOs # Turn off the RGB GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) # Reset the GPIO status GPIO.cleanup() ### Error occured except (KeyboardInterrupt, SystemExit): ### Configuration GPIOs # Turn of the RGB GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) # Reset the GPIO status GPIO.cleanup() print("Excpetion:") print("\nKilling Threads..") ### Buffer to file # Append the buffer data to the CSV file log.appendFile() ### End threads # End the GPS polling thread gpsp.running = False gpsp.join() # End the temperature polling thread temperature.running = False temperature.join() ### Disconnect OBD # Stop the connection to the OBD connection.stop()
def main(): GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.OUT) GPIO.setup(27, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setwarnings(False) RGBblue = 17 RGBred = 27 RGBgreen = 22 GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) GPIO.output(RGBred, GPIO.HIGH) GPIO.output(RGBgreen, GPIO.HIGH) gpsp = GpsPoller() #Start GPS thread gpsp.start() temperature = TempPoller() #Start temperature thread temperature.start() i = 0 #This line counter for output file is needed to manage different sample rates connection = None NotConnected = True errorcnt = 0 #Error count to detect the moment if ignition is off at the end of a Driving Cycle HasConnection = True OnlyGPSMode = 0 OBDError = 0 filename = datetime.datetime.now().strftime( "%y_%m_%d_%H:%M:%S_") + "test.csv" start = uptime() #Try to establish a connection with the OBD dongle while NotConnected: try: connection = obd.OBD() #Try to connect to OBD dongle print(connection.status()) #Print OBD Status for debugging #if the return of query RPM signal is not null --> Connecting succeeded if (connection.status() == obd.utils.OBDStatus.CAR_CONNECTED and (connection.query(obd.commands.RPM).is_null() == False)): NotConnected = False print("Successful connected to OBDII!" ) #Connecting to OBD dongle succeeded time.sleep(1) else: time.sleep( 1) #Sleep 1s before trying to connect to OBD dongle again except: print("Error Connecting to OBD-Adapter (" + str(OBDError) + ")") time.sleep(1) OBDError += 1 if (OBDError == 10): NotConnected = False OnlyGPSMode = 1 log = LogFile() OBDError = 0 temp = True stri = "" stri_end = "" #Handle only GPS Mode: check if GPS data is available while (temp and OnlyGPSMode == 1): report = gpsp.get_current_value() if report['class'] == 'TPV': if hasattr(report, 'lon') and hasattr(report, 'lat') and hasattr( report, 'alt'): print("GPS found-> Only GPS Mode") #Set Colour to Cyan GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) stri = "GPS_" stri_end = "x" OnlyGPSMode = 2 temp = False else: time.sleep(1) #Create logfile log.createLogfile(stri + filename + stri_end) vin = None start = uptime() try: #Only GPS Mode while (OnlyGPSMode == 2): i = i + 1 if (i == 2048): i = 0 GPS_Only(log, i, start, temperature, gpsp) if (connection.status() == obd.utils.OBDStatus.CAR_CONNECTED and HasConnection): c = OBDCommand("VIN", "Get Vehicle Identification Number", b"0902", 20, raw_string, ECU.ENGINE, False) response = connection.query(c, force=True) vin = LogFile.parseVIN(response.value) print(vin) #connection.close() #change to asynchronous connection connection = obd.Async() connection.watch(obd.commands.RPM) # keep track of the RPM for signal in signals.getOBDSignalList(): connection.watch( obd.commands[signal.name]) # keep track of the RPM connection.start() time.sleep(0.5) #Set Colour to pink GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.output(RGBblue, GPIO.HIGH) GPIO.output(RGBred, GPIO.HIGH) #Normal Mode: OBD-, GPS-, Temperature-Data while (connection.status() == obd.utils.OBDStatus.CAR_CONNECTED and HasConnection): #Error handling to detect IGNITION OFF Signal if (connection.query(obd.commands.RPM).is_null() == True): print("Error") errorcnt += 1 print(errorcnt) else: errorcnt = 0 if (errorcnt >= 5): print("End: Too many Errors - Ignition seems to be off") HasConnection = False GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) i = i + 1 if (i == 2048): i = 0 #Get actual time data #timestr = str(datetime.datetime.now()) timestr = uptime() timestr = timestr - start result = [] result.append(timestr) #Set the GPS and Temperature variables to initial value lon = None lat = None gpsTime = None internalTemp = None alt = None #Get GPS data (if possible) if (i % signals.getSignal("GPS_Long").sampleRate == 0): report = gpsp.get_current_value() (lon, lat, alt, gpsTime) = getGpsData(report) #Get internal tempterature data if (i % signals.getSignal("INTERNAL_AIR_TEMP").sampleRate == 0): internalTemp = temperature.get_current_value() #Get OBD data for signal in signals.getOBDSignalList(): if (i % signal.sampleRate == 0 ): #Handle different Sample Rates r = connection.query(obd.commands[signal.name]) if r.is_null(): result.append(0) else: result.append(r.value.magnitude) else: result.append(None) #Appending GPS-Data (if available) result.append(lon) result.append(lat) result.append(alt) result.append(gpsTime) #Append Temperature-Data (if available) result.append(internalTemp) result.append(vin) #write all data to file log.addData(result) if (vin != None ): #write vin to file only once to readuce ammount of data vin = None time.sleep(0.5) #Sleep 500ms to get not that much ammount of data if (i % 20 == 0): #Appand file every 20 rows of measurement data log.appendFile() print("Appending File ...") log.appendFile() print("Ignition Off") print("\nKilling Threads..") gpsp.running = False gpsp.join() temperature.running = False temperature.join() connection.stop() GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.cleanup() except (KeyboardInterrupt, SystemExit): GPIO.output(RGBblue, GPIO.LOW) GPIO.output(RGBred, GPIO.LOW) GPIO.output(RGBgreen, GPIO.LOW) GPIO.cleanup() print("Excpetion:") print("\nKilling Threads..") log.appendFile() gpsp.running = False gpsp.join() temperature.running = False temperature.join() connection.stop()