def __init__(self, methodName='runTest'): super().__init__(methodName) self.test_online = os.environ.get("TEST_ONLINE", "0") == "1" self.vehicule_list = Cars() self.vehicule_list.extend([ Car("VR3UHZKX", "vid", "Peugeot"), Car("VXXXXX", "XXXX", "Peugeot", label="SUV 3008") ])
def record_to_db(file_name): myfile = open(file_name, 'w', encoding='cp1251') for n, l, f, p in zip(names_list, links, photos, list_price): # db_session.add(1,2,3,4) # # libs.car.add_cars(n, l, f, p) db_session.add(Cars(n, l, f, p)) db_session.commit() try: line = '{}{}{}{}{}'.format(n, '\t', l, '\t', f, '\t', str(p)) myfile.write(line + '\n') except: pass
def update_trips(): global trips, chargings, cached_layout, min_date, max_date, min_millis, max_millis, step, marks logger.info("update_data") conn = Database.get_db(update_callback=False) Database.add_altitude_to_db(conn) conn.close() min_date = None max_date = None if CONFIG.is_good: car = CONFIG.myp.vehicles_list[0] # todo handle multiple car try: trips_by_vin = Trips.get_trips(Cars([car])) trips = trips_by_vin[car.vin] assert len(trips) > 0 min_date = trips[0].start_at max_date = trips[-1].start_at figures.get_figures(trips[0].car) except (AssertionError, KeyError): logger.debug("No trips yet") figures.get_figures(Car("vin", "vid", "brand")) try: chargings = Charging.get_chargings() assert len(chargings) > 0 if min_date: min_date = min(min_date, chargings[0]["start_at"]) max_date = max(max_date, chargings[-1]["start_at"]) else: min_date = chargings[0]["start_at"] max_date = chargings[-1]["start_at"] except AssertionError: logger.debug("No chargings yet") if min_date is None: return # update for slider try: logger.debug("min_date:%s - max_date:%s", min_date, max_date) min_millis = web.utils.unix_time_millis(min_date) max_millis = web.utils.unix_time_millis(max_date) step = (max_millis - min_millis) / 100 marks = web.utils.get_marks_from_start_end(min_date, max_date) cached_layout = None # force regenerate layout figures.get_figures(car) except (ValueError, IndexError): logger.error("update_trips (slider): %s", exc_info=True) except AttributeError: logger.debug("position table is probably empty :", exc_info=True) return
def __init__(self, refresh_token, client_id, client_secret, remote_refresh_token, customer_id, realm, country_code, proxies=None, weather_api=None, abrp=None, co2_signal_api=None): self.realm = realm self.service_information = ServiceInformation(AUTHORIZE_SERVICE, realm_info[self.realm]['oauth_url'], client_id, client_secret, SCOPE, False) self.client_id = client_id self.manager = OpenIdCredentialManager(self.service_information) self.api_config = Oauth2PSACCApiConfig() self.api_config.set_refresh_callback(self.refresh_token) self.manager.refresh_token = refresh_token self.remote_refresh_token = remote_refresh_token self.remote_access_token = None self.vehicles_list = Cars.load_cars(CARS_FILE) self.customer_id = customer_id self._config_hash = None self.api_config.verify_ssl = False self.api_config.api_key['client_id'] = self.client_id self.api_config.api_key['x-introspect-realm'] = self.realm self.headers = { "x-introspect-realm": realm, "accept": "application/hal+json", "User-Agent": "okhttp/4.8.0", } self.remote_token_last_update = None self._record_enabled = False self.otp = None self.weather_api = weather_api self.country_code = country_code self.mqtt_client = None self.precond_programs = {} self.info_callback = [] self.info_refresh_rate = 120 if abrp is None: self.abrp = Abrp() else: self.abrp: Abrp = Abrp(**abrp) self.set_proxies(proxies) self.config_file = DEFAULT_CONFIG_FILENAME Ecomix.co2_signal_key = co2_signal_api
def __init__(self, refresh_token, client_id, client_secret, remote_refresh_token, customer_id, realm, country_code, proxies=None, weather_api=None, abrp=None, co2_signal_api=None): self.realm = realm self.service_information = ServiceInformation(AUTHORIZE_SERVICE, realm_info[self.realm]['oauth_url'], client_id, client_secret, SCOPE, False) self.client_id = client_id self.manager = OpenIdCredentialManager(self.service_information) self.api_config = Oauth2PSACCApiConfig() self.api_config.set_refresh_callback(self.manager.refresh_token_now) self.manager.refresh_token = refresh_token self.account_info = AccountInformation(client_id, customer_id, realm, country_code) self.remote_access_token = None self.vehicles_list = Cars.load_cars(CARS_FILE) self.customer_id = customer_id self._config_hash = None self.api_config.verify_ssl = False self.api_config.api_key['client_id'] = self.client_id self.api_config.api_key['x-introspect-realm'] = self.realm self.remote_token_last_update = None self._record_enabled = False self.weather_api = weather_api self.country_code = country_code self.info_callback = [] self.info_refresh_rate = 120 if abrp is None: self.abrp = Abrp() else: self.abrp: Abrp = Abrp(**abrp) self.set_proxies(proxies) self.config_file = DEFAULT_CONFIG_FILENAME Ecomix.co2_signal_key = co2_signal_api self.refresh_thread = None remote_credentials = RemoteCredentials(remote_refresh_token) remote_credentials.update_callbacks.append(self.save_config) self.remote_client = RemoteClient(self.account_info, self.vehicles_list, self.manager, remote_credentials)
def work(self, wnum): self.log.debug(f'{wnum} worker started') rab_connection = RabbitQueue(CRAWLER_EXCHANGE_NAME, CRAWLER_QUEUE_NAME) db_connection = DbPg(logger=None) for raw_msg in rab_connection.get_generator(self.exit_event): if not raw_msg: if self.exit_event.wait(2): break continue msg = raw_msg.json() print(msg) if 'url' not in msg: self.log.warning(f'{wnum}: bad task: {msg}') raw_msg.ack() continue print() if msg['num'] == 0: msg['url'] = PAGE_URL0 print("0", msg) try: request = requests.get(msg['url'], headers=HEADERS).content soup = BeautifulSoup(request, 'html.parser') self.log.debug(msg['url']) time.sleep(1) names_list = [] container_names = soup.select('div.information-container h2 a') for name in container_names: str_name = name.text print(str_name) names_list.append(str_name) links = [] container_links = soup.select('div.information-container h2 a') for i in container_links: ii = i['href'].split("&")[0] full_link = ("https://www.autotrader.co.uk" + ii) link = full_link.split('?')[0] links.append(link) photos = [] container_photo = soup.select( 'figure.listing-main-image a img') for link_photo in container_photo: photos.append(link_photo['src']) list_price = [] container_text = soup.find_all( "a", attrs={ "class": "js-click-handler listing-fpa-link listings-price-link tracking-standard-link" }) for i in container_text: pr = i.find_all("div", attrs={"class": "vehicle-price"}) str_price = "".join((re.findall(r'[0-9]{,3},[0-9]{,3}', str(pr)))) price = 27 * int(str_price.replace(',', '')) list_price.append(price) for n, l, f, p in zip(names_list, links, photos, list_price): db_session.add(Cars(n, l, f, p)) db_session.commit() data = '{}{}{}{}{}'.format(n, '\t', l, '\t', f, '\t', str(p)) self.log.debug(data) db_session.add(Pages(msg['num'])) db_session.commit() raw_msg.ack() except Exception as e0: self.log.exception()( f'{wnum}: get page error: {e0}') ##self.log.error raw_msg.nack(requeue=True) prox = None if USE_PROXY: self.proxy_gen.back_proxy(prox, str(e0)) time.sleep(random.randrange(1, 5)) rab_connection.close() self.log.info(f'{wnum}: worker exit')
def get_trips(vehicles_list: Cars) -> Dict[str, "Trips"]: # noqa: MC0001 # pylint: disable=too-many-locals,too-many-statements,too-many-nested-blocks,too-many-branches conn = Database.get_db() vehicles = conn.execute( "SELECT DISTINCT vin FROM position;").fetchall() trips_by_vin = {} for vin in vehicles: trips = Trips() vin = vin[0] res = conn.execute( 'SELECT Timestamp, VIN, longitude, latitude, mileage, level, moving, temperature,' ' level_fuel, altitude FROM position WHERE VIN=? ORDER BY Timestamp', (vin, )).fetchall() if len(res) > 1: car = vehicles_list.get_car_by_vin(vin) assert car is not None trip_parser = TripParser(car) start = res[0] end = res[1] trip = Trip() # for debugging use this line res = list(map(dict,res)) for x in range(0, len(res) - 2): if logger.isEnabledFor( logging.DEBUG ): # reduce execution time if debug disabled logger.debugv("%s mileage:%.1f level:%s level_fuel:%s", res[x]['Timestamp'], res[x]['mileage'], res[x]['level'], res[x]['level_fuel']) next_el = res[x + 2] distance = 0 try: distance = end["mileage"] - start["mileage"] except TypeError: logger.debug("Bad mileage value in DB") duration = (end["Timestamp"] - start["Timestamp"]).total_seconds() / 3600 try: speed_average = distance / duration except ZeroDivisionError: speed_average = 0 if TripParser.is_low_speed( speed_average, duration) or trip_parser.is_refuel( start, end, distance): start = end trip = Trip() logger.debugv( "restart trip at {0[Timestamp]} mileage:{0[mileage]:.1f} level:{0[level]}" " level_fuel:{0[level_fuel]}", start, style='{') else: distance = next_el["mileage"] - end["mileage"] # km duration = (next_el["Timestamp"] - end["Timestamp"]).total_seconds() / 3600 try: speed_average = distance / duration except ZeroDivisionError: speed_average = 0 end_trip = False if trip_parser.is_refuel(end, next_el, distance) or \ TripParser.is_low_speed(speed_average, duration): end_trip = True elif duration > 2: end_trip = True logger.debugv("too much time detected") elif x == len(res) - 3: # last record detected # think if add point is needed end = next_el end_trip = True logger.debugv("last position found") if end_trip: logger.debugv( "stop trip at {0[Timestamp]} mileage:{0[mileage]:.1f} level:{0[level]}" " level_fuel:{0[level_fuel]}", end, style='{') trip.distance = end["mileage"] - start[ "mileage"] # km if trip.distance > 0: trip.start_at = start["Timestamp"] trip.end_at = end["Timestamp"] trip.add_points(end["latitude"], end["longitude"]) if end["temperature"] is not None and start[ "temperature"] is not None: trip.add_temperature(end["temperature"]) trip.duration = ( end["Timestamp"] - start["Timestamp"]).total_seconds() / 3600 trip.speed_average = trip.distance / trip.duration diff_level, diff_level_fuel = trip_parser.get_level_consumption( start, end) trip.set_altitude_diff(start["altitude"], end["altitude"]) trip.car = car if diff_level != 0: trip.set_consumption(diff_level) # kw if diff_level_fuel != 0: trip.set_fuel_consumption(diff_level_fuel) trip.mileage = end["mileage"] logger.debugv( "Trip: {0.start_at} -> {0.end_at} {0.distance:.1f}km {0.duration:.2f}h " "{0.speed_average:.0f}km/h {0.consumption:.2f}kWh " "{0.consumption_km:.2f}kWh/100km {0.consumption_fuel:.2f}L " "{0.consumption_fuel_km:.2f}L/100km {0.mileage:.1f}km", trip, style="{") # filter bad value trips.check_and_append(trip) start = next_el trip = Trip() else: trip.add_points(end["latitude"], end["longitude"]) end = next_el trips_by_vin[vin] = trips conn.close() return trips_by_vin
import pytz from libs.car import Car, Cars from libs.charging import Charging from web.db import Database DATA_DIR = os.path.dirname(os.path.realpath(__file__)) + "/data/" latitude = 47.2183 longitude = -1.55362 date3 = datetime.utcnow().replace(2021, 3, 1, 12, 00, 00, 00, tzinfo=pytz.UTC) date2 = date3 - timedelta(minutes=20) date1 = date3 - timedelta(minutes=40) date0 = date3 - timedelta(minutes=60) date4 = date3 + timedelta(minutes=1) vehicule_list = Cars() vehicule_list.extend( [Car("VR3UHZKX", "vid", "Peugeot"), Car("VXXXXX", "XXXX", "Peugeot", label="SUV 3008 Hybrid 225")]) car = vehicule_list[0] DB_DIR = DATA_DIR + "tmp.db" def get_new_test_db(): try: os.remove(DATA_DIR + "tmp.db") except FileNotFoundError: pass Database.DEFAULT_DB_FILE = DB_DIR Database.db_initialized = False conn = Database.get_db() return conn
def work(self, wnum): self.log.debug(f'{wnum} worker started') rab_connection = RabbitQueue(CRAWLER_EXCHANGE_NAME, CRAWLER_QUEUE_NAME) db_connection = DbPg(logger=None) # driver, prox = self.init_browser() for raw_msg in rab_connection.get_generator(self.exit_event): if not raw_msg: if self.exit_event.wait(2): break continue msg = raw_msg.json() print(msg) if 'url' not in msg: self.log.warning(f'{wnum}: bad task: {msg}') raw_msg.ack() continue print() if msg['num'] == 0: msg['url'] = PAGE_URL0 # msg['url'] = msg['url'].split('?')[0] print("0",msg) try: # driver.get(msg['url']) request = requests.get(msg['url'], headers=HEADERS).content soup = BeautifulSoup(request, 'html.parser') # container = soup.select("li.search-page__result") self.log.debug(msg['url']) # self.log.debug(driver.current_url) time.sleep(1) names_list = [] container_names = soup.select('div.information-container h2 a') for name in container_names: str_name = name.text #name = str_name.strip() print(str_name) names_list.append(str_name) links = [] container_links = soup.select('div.information-container h2 a') for i in container_links: ii = i['href'].split("&")[0] # ii = i['href'] full_link = ("https://www.autotrader.co.uk" + ii) link = full_link.split('?')[0] links.append(link) #print(link) photos = [] container_photo = soup.select('figure.listing-main-image a img') for link_photo in container_photo: photos.append(link_photo['src']) #print(link_photo['src']) list_price = [] container_text = soup.find_all("a", attrs={ "class" : "js-click-handler listing-fpa-link listings-price-link tracking-standard-link"}) for i in container_text: pr = i.find_all("div", attrs={ "class" : "vehicle-price"}) str_price = "".join((re.findall(r'[0-9]{,3},[0-9]{,3}', str(pr)))) price =27*int(str_price.replace(',', '')) list_price.append(price) for n, l, f, p in zip(names_list, links, photos, list_price): db_session.add(Cars(n, l, f, p)) db_session.commit() data = '{}{}{}{}{}'.format(n, '\t', l, '\t', f, '\t',str(p)) # parse with selenium # rows = driver.find_elements_by_css_selector("tr") # if not rows: # self.log.debug(f'{wnum}: not rows in table') # raw_msg.nack(requeue=True) # break # # for row in rows: # cells = row.find_elements_by_css_selector("td") # if not cells: # continue # # data = { # 'img_url': cells[0].find_element_by_css_selector( # 'img').get_attribute('src'), # 'country': cells[1].find_element_by_css_selector( # 'span').get_attribute('title'), # 'vessel_name': cells[1].text.split('\n')[0], # 'vessel_type': cells[1].text.split('\n')[1], # 'year': cells[2].text, # 'gt': cells[3].text, # 'dwt': cells[4].text, # 'sz': cells[5].text # } # vlength, vwidth = [int(v.strip()) for v in data['sz'].split('/')] self.log.debug(data) # db_connection.insert_ship(car) # db_connection.exec_query(f''' # INSERT INTO pages (page_num) # VALUES({msg['num']}) # ''') db_session.add(Pages(msg['num'])) db_session.commit() raw_msg.ack() except Exception as e0: self.log.exception()(f'{wnum}: get page error: {e0}')##self.log.error raw_msg.nack(requeue=True) prox = None if USE_PROXY: self.proxy_gen.back_proxy(prox, str(e0)) # driver.close() # driver, prox = self.init_browser() time.sleep(random.randrange(1, 5)) rab_connection.close() # db_connection.close() self.log.info(f'{wnum}: worker exit')
def test_car(self): car1 = Car("VRAAAAAAA", "1sdfdksnfk222", "Peugeot", "208", 46, 0) car2 = Car("VR3UHZKX", "1sdfdksnfk222", "Peugeot") cars = Cars([car1, car2]) cars.save_cars(name=DATA_DIR + "test_car.json") Cars.load_cars(name=DATA_DIR + "test_car.json")
class TestUnit(unittest.TestCase): def __init__(self, methodName='runTest'): super().__init__(methodName) self.test_online = os.environ.get("TEST_ONLINE", "0") == "1" self.vehicule_list = Cars() self.vehicule_list.extend([ Car("VR3UHZKX", "vid", "Peugeot"), Car("VXXXXX", "XXXX", "Peugeot", label="SUV 3008") ]) @staticmethod def get_new_test_db(): try: os.remove(DATA_DIR + "tmp.db") except: pass Database.DEFAULT_DB_FILE = DATA_DIR + "tmp.db" Database.db_initialized = False conn = Database.get_db() return conn def test_car(self): car1 = Car("VRAAAAAAA", "1sdfdksnfk222", "Peugeot", "208", 46, 0) car2 = Car("VR3UHZKX", "1sdfdksnfk222", "Peugeot") cars = Cars([car1, car2]) cars.save_cars(name=DATA_DIR + "test_car.json") Cars.load_cars(name=DATA_DIR + "test_car.json") def test_otp_config(self): otp_config = load_otp(filename=DATA_DIR + "otp_test.bin") assert otp_config is not None save_otp(otp_config, filename=DATA_DIR + "otp_test2.bin") def test_mypsacc(self): if self.test_online: myp = MyPSACC.load_config("config.json") myp.refresh_token() myp.get_vehicles() car = myp.vehicles_list[0] myp.abrp.abrp_enable_vin.add(car.vin) res = myp.get_vehicle_info(myp.vehicles_list[0].vin) myp.abrp.call(car, 22.1) myp.save_config() assert isinstance( get_temp(str(latitude), str(longitude), myp.weather_api), float) def test_car_model(self): assert CarModel.find_model_by_vin("VR3UHZKXZL").name == "e-208" assert CarModel.find_model_by_vin("VR3UKZKXZM").name == "e-2008" assert CarModel.find_model_by_vin("VXKUHZKXZL").name == "corsa-e" def test_c02_signal_cache(self): start = datetime.now() - timedelta(minutes=30) end = datetime.now() Ecomix._cache = { 'FR': [[start - timedelta(days=1), 100], [start + timedelta(minutes=1), 10], [start + timedelta(minutes=2), 20], [start + timedelta(minutes=3), 30]] } assert Ecomix.get_co2_from_signal_cache(start, end, "FR") == 20 def test_c02_signal(self): if self.test_online: key = "d186c74bfbcd1da8" Ecomix.co2_signal_key = key def_country = "FR" Ecomix.get_data_from_co2_signal(latitude, longitude, def_country) res = Ecomix.get_co2_from_signal_cache( datetime.now() - timedelta(minutes=5), datetime.now(), def_country) assert isinstance(res, float) def test_charge_control(self): charge_control = ChargeControls() charge_control.file_name = "test_charge_control.json" charge_control.save_config(force=True) def test_battery_curve(self): from libs.car import Car from libs.charging import Charging try: os.remove("tmp.db") except: pass Database.DEFAULT_DB_FILE = "tmp.db" conn = Database.get_db() list(map(dict, conn.execute('PRAGMA database_list').fetchall())) vin = "VR3UHZKXZL" car = Car(vin, "id", "Peugeot") Charging.record_charging(car, "InProgress", date0, 50, latitude, longitude, "FR", "slow") Charging.record_charging(car, "InProgress", date1, 75, latitude, longitude, "FR", "slow") Charging.record_charging(car, "InProgress", date2, 85, latitude, longitude, "FR", "slow") Charging.record_charging(car, "InProgress", date3, 90, latitude, longitude, "FR", "slow") res = Database.get_battery_curve(Database.get_db(), date0, vin) assert len(res) == 3 def test_sdk(self): res = { 'lastPosition': { 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [9.65457, 49.96119, 21] }, 'properties': { 'updatedAt': '2021-03-29T05:16:10Z', 'heading': 126, 'type': 'Estimated' } }, 'preconditionning': { 'airConditioning': { 'updatedAt': '2021-04-01T16:17:01Z', 'status': 'Disabled', 'programs': [{ 'enabled': False, 'slot': 1, 'recurrence': 'Daily', 'start': 'PT21H40M', 'occurence': { 'day': ['Sat'] } }] } }, 'energy': [{ 'updatedAt': '2021-02-23T22:29:03Z', 'type': 'Fuel', 'level': 0 }, { 'updatedAt': '2021-04-01T16:17:01Z', 'type': 'Electric', 'level': 70, 'autonomy': 192, 'charging': { 'plugged': False, 'status': 'Disconnected', 'remainingTime': 'PT0S', 'chargingRate': 0, 'chargingMode': 'No', 'nextDelayedTime': 'PT21H30M' } }], 'createdAt': '2021-04-01T16:17:01Z', 'battery': { 'voltage': 99, 'current': 0, 'createdAt': '2021-04-01T16:17:01Z' }, 'kinetic': { 'createdAt': '2021-03-29T05:16:10Z', 'moving': False }, 'privacy': { 'createdAt': '2021-04-01T16:17:01Z', 'state': 'None' }, 'service': { 'type': 'Electric', 'updatedAt': '2021-02-23T21:10:29Z' }, '_links': { 'self': { 'href': 'https://api.groupe-psa.com/connectedcar/v4/user/vehicles/myid/status' }, 'vehicles': { 'href': 'https://api.groupe-psa.com/connectedcar/v4/user/vehicles/myid' } }, 'timed.odometer': { 'createdAt': None, 'mileage': 1107.1 }, 'updatedAt': '2021-04-01T16:17:01Z' } api = ApiClient() status: psacc.models.status.Status = api._ApiClient__deserialize( res, "Status") geocode_res = reverse_geocode.search([ (status.last_position.geometry.coordinates[:2])[::-1] ])[0] assert geocode_res["country_code"] == "DE" TestUnit.get_new_test_db() car = Car("XX", "vid", "Peugeot") car.status = status myp = MyPSACC.load_config(DATA_DIR + "config.json") myp.record_info(car) assert "features" in json.loads(Database.get_recorded_position()) # electric should be first assert car.status.energy[0].type == 'Electric' def test_record_position_charging(self): TestUnit.get_new_test_db() ElecPrice.CONFIG_FILENAME = DATA_DIR + "config.ini" car = self.vehicule_list[0] Database.record_position(None, car.vin, 11, latitude, longitude - 0.05, None, date0, 40, None, False) Database.record_position(None, car.vin, 20, latitude, longitude, 32, date1, 35, None, False) Database.record_position(None, car.vin, 30, latitude, longitude, 42, date2, 30, None, False) Database.add_altitude_to_db(Database.get_db()) data = json.loads(Database.get_recorded_position()) assert data["features"][1]["geometry"]["coordinates"] == [ float(longitude), float(latitude) ] trips = Trips.get_trips(self.vehicule_list)[car.vin] trip = trips[0] map(trip.add_temperature, [10, 13, 15]) res = trip.get_info() assert compare_dict( res, { 'consumption_km': 24.21052631578947, 'start_at': date0, 'consumption_by_temp': None, 'positions': { 'lat': [latitude], 'long': [longitude] }, 'duration': 40.0, 'speed_average': 28.5, 'distance': 19.0, 'mileage': 30.0, 'altitude_diff': 2, 'id': 1, 'consumption': 4.6 }) Charging.elec_price = ElecPrice.read_config() start_level = 40 end_level = 85 Charging.record_charging(car, "InProgress", date0, start_level, latitude, longitude, None, "slow") Charging.record_charging(car, "InProgress", date1, 70, latitude, longitude, "FR", "slow") Charging.record_charging(car, "InProgress", date1, 70, latitude, longitude, "FR", "slow") Charging.record_charging(car, "InProgress", date2, 80, latitude, longitude, "FR", "slow") Charging.record_charging(car, "Stopped", date3, end_level, latitude, longitude, "FR", "slow") chargings = Charging.get_chargings() co2 = chargings[0]["co2"] assert isinstance(co2, float) assert compare_dict(chargings, [{ 'start_at': date0, 'stop_at': date3, 'VIN': 'VR3UHZKX', 'start_level': 40, 'end_level': 85, 'co2': co2, 'kw': 20.7, 'price': 3.84, 'charging_mode': 'slow' }]) assert get_figures(car) row = { "start_at": date0.strftime('%Y-%m-%dT%H:%M:%S.000Z'), "stop_at": date3.strftime('%Y-%m-%dT%H:%M:%S.000Z'), "start_level": start_level, "end_level": end_level } assert get_battery_curve_fig(row, car) is not None assert get_altitude_fig(trip) is not None def test_fuel_car(self): TestUnit.get_new_test_db() ElecPrice.CONFIG_FILENAME = DATA_DIR + "config.ini" car = self.vehicule_list[1] Database.record_position(None, car.vin, 11, latitude, longitude, 22, date0, 40, 30, False) Database.record_position(None, car.vin, 20, latitude, longitude, 22, date1, 35, 29, False) Database.record_position(None, car.vin, 30, latitude, longitude, 22, date2, 30, 28, False) trips = Trips.get_trips(self.vehicule_list) res = trips[car.vin].get_trips_as_dict() assert compare_dict(res, [{ 'consumption_km': 5.684210526315789, 'start_at': date0, 'consumption_by_temp': None, 'positions': { 'lat': [latitude], 'long': [longitude] }, 'duration': 40.0, 'speed_average': 28.5, 'distance': 19.0, 'mileage': 30.0, 'altitude_diff': 0, 'id': 1, 'consumption': 1.08, 'consumption_fuel_km': 10.53 }]) def test_db_callback(self): old_dummy_value = dummy_value TestUnit.get_new_test_db() Database.set_db_callback(callback_test) assert old_dummy_value == dummy_value Database.record_position(None, "xx", 11, latitude, longitude - 0.05, None, date0, 40, None, False) assert old_dummy_value != dummy_value def test_parse_hour(self): expected_res = [(2, 0, 0), (3, '14', 0), (0, 0, '2')] assert expected_res == [ parse_hour(h) for h in ["PT2H", "PT3H14", "PT2S"] ]