fix things, some things should work
This commit is contained in:
@@ -1,43 +1,44 @@
|
|||||||
from flask import Flask, render_template, make_response, json
|
from flask import Flask, render_template, make_response, json
|
||||||
import modules.app_obd, modules.app_car, modules.app_account, modules.app_gps, time
|
from modules import app_gps, app_events, app_car, app_account, app_gps,app_obd
|
||||||
from modules.app_events import socketio
|
import time
|
||||||
from gevent.pywsgi import WSGIServer
|
from gevent.pywsgi import WSGIServer
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
socketio.init_app(app)
|
app = Flask(__name__)
|
||||||
|
app_events.socketio.init_app(app)
|
||||||
account = modules.app_account.Account()
|
|
||||||
obd = modules.app_obd.OBD()
|
account = app_account.Account()
|
||||||
car = modules.app_car.Car()
|
obd = app_obd.OBD()
|
||||||
gps = modules.app_gps.get_gps()
|
car = app_car.Car()
|
||||||
|
gps = app_gps.get_gps()
|
||||||
@app.route('/')
|
|
||||||
def index():
|
@app.route('/')
|
||||||
print("hello "+ account.name)
|
def index():
|
||||||
print("you're car model is:" + car.model)
|
print("hello "+ account.name)
|
||||||
return render_template('index.html', account = account, car = car)
|
print("you're car model is:" + car.model)
|
||||||
|
return render_template('index.html', account = account, car = car)
|
||||||
@app.route('/dtc')
|
|
||||||
def dtc():
|
@app.route('/dtc')
|
||||||
return render_template('dtc.html', account = account, car = car)
|
def dtc():
|
||||||
|
return render_template('dtc.html', account = account, car = car)
|
||||||
@app.route('/dash')
|
|
||||||
def dash():
|
@app.route('/dash')
|
||||||
return render_template('dash.html', account = account, car = car)
|
def dash():
|
||||||
|
return render_template('dash.html', account = account, car = car)
|
||||||
# not sure if im gonna use this
|
|
||||||
@app.route('/api/obd_speed/')
|
# not sure if im gonna use this
|
||||||
def data():
|
@app.route('/api/obd_speed/')
|
||||||
data = app_obd.speed
|
def data():
|
||||||
response = make_response(json.dumps(data))
|
data = app_obd.speed
|
||||||
response.content_type = 'application/json'
|
response = make_response(json.dumps(data))
|
||||||
return response
|
response.content_type = 'application/json'
|
||||||
|
return response
|
||||||
if __name__ == '__main__':
|
|
||||||
# Debug/Development
|
if __name__ == '__main__':
|
||||||
# app.run(debug=True, host="0.0.0.0", port="5000")
|
# Debug/Development
|
||||||
# Production
|
# app.run(debug=True, host="0.0.0.0", port="5000")
|
||||||
http_server = WSGIServer(('', 5000), app)
|
# Production
|
||||||
print("server on :5000")
|
http_server = WSGIServer(('', 5000), app)
|
||||||
http_server.serve_forever()
|
print("server on http://localhost:5000")
|
||||||
|
http_server.serve_forever()
|
||||||
|
|
||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
##
|
##
|
||||||
## MangoDB server connection details
|
## MangoDB server connection details
|
||||||
##
|
##
|
||||||
|
|
||||||
mangosrv_user = ""
|
mangosrv_user = ""
|
||||||
mangosrv_pass = ""
|
mangosrv_pass = ""
|
||||||
mangosrv_db = ""
|
mangosrv_db = ""
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
class Account:
|
class Account:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = "quoije"
|
self.name = "quoije"
|
||||||
self.pp_image = None
|
self.pp_image = None
|
||||||
self.car = None
|
self.car = None
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
class Car:
|
class Car:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.model = "Yaris 2013"
|
self.model = "Yaris 2013"
|
||||||
self.obd = None
|
self.obd = None
|
||||||
+37
-37
@@ -1,38 +1,38 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
def mount_device(device, mount_point):
|
def mount_device(device, mount_point):
|
||||||
os.system(f"sudo mount {device} {mount_point}")
|
os.system(f"sudo mount {device} {mount_point}")
|
||||||
|
|
||||||
def unmount_device(mount_point):
|
def unmount_device(mount_point):
|
||||||
os.system(f"sudo umount {mount_point}")
|
os.system(f"sudo umount {mount_point}")
|
||||||
|
|
||||||
def copy_files(source_folder, destination_folder):
|
def copy_files(source_folder, destination_folder):
|
||||||
if not os.path.exists(destination_folder):
|
if not os.path.exists(destination_folder):
|
||||||
os.makedirs(destination_folder)
|
os.makedirs(destination_folder)
|
||||||
|
|
||||||
for root, dirs, files in os.walk(source_folder):
|
for root, dirs, files in os.walk(source_folder):
|
||||||
for file in tqdm(files, desc="Copying files", unit="file"):
|
for file in tqdm(files, desc="Copying files", unit="file"):
|
||||||
source_path = os.path.join(root, file)
|
source_path = os.path.join(root, file)
|
||||||
destination_path = os.path.join(destination_folder, file)
|
destination_path = os.path.join(destination_folder, file)
|
||||||
|
|
||||||
# Check if the file already exists in the destination folder
|
# Check if the file already exists in the destination folder
|
||||||
if not os.path.exists(destination_path):
|
if not os.path.exists(destination_path):
|
||||||
shutil.copy2(source_path, destination_folder)
|
shutil.copy2(source_path, destination_folder)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
source_device = "/dev/sda"
|
source_device = "/dev/sda"
|
||||||
mount_point = "/mnt/dash"
|
mount_point = "/mnt/dash"
|
||||||
destination_folder = "~/yaris-obd/dash/videos"
|
destination_folder = "~/yaris-obd/dash/videos"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Mount the device
|
# Mount the device
|
||||||
mount_device(source_device, mount_point)
|
mount_device(source_device, mount_point)
|
||||||
|
|
||||||
# Copy files from source to destination
|
# Copy files from source to destination
|
||||||
copy_files(os.path.join(mount_point, "DCIM"), os.path.expanduser(destination_folder))
|
copy_files(os.path.join(mount_point, "DCIM"), os.path.expanduser(destination_folder))
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# Unmount the device (even if an exception occurs)
|
# Unmount the device (even if an exception occurs)
|
||||||
unmount_device(mount_point)
|
unmount_device(mount_point)
|
||||||
+22
-22
@@ -1,23 +1,23 @@
|
|||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import os
|
import os
|
||||||
|
|
||||||
load_dotenv("../db/creds.env")
|
load_dotenv("../db/creds.env")
|
||||||
|
|
||||||
mUser = os.getenv()
|
mUser = os.getenv()
|
||||||
mPass = os.getenv()
|
mPass = os.getenv()
|
||||||
mDB = os.getenv()
|
mDB = os.getenv()
|
||||||
|
|
||||||
def get_database():
|
def get_database():
|
||||||
|
|
||||||
# Provide the mongodb atlas url to connect python to mongodb using pymongo
|
# Provide the mongodb atlas url to connect python to mongodb using pymongo
|
||||||
CONNECTION_STRING = "mongodb+srv://"+ mUser + ":" + mPass + "@cluster.mongodb.net/" + mDB
|
CONNECTION_STRING = "mongodb+srv://"+ mUser + ":" + mPass + "@cluster.mongodb.net/" + mDB
|
||||||
|
|
||||||
# Create a connection using MongoClient. You can import MongoClient or use pymongo.MongoClient
|
# Create a connection using MongoClient. You can import MongoClient or use pymongo.MongoClient
|
||||||
client = MongoClient(CONNECTION_STRING)
|
client = MongoClient(CONNECTION_STRING)
|
||||||
|
|
||||||
# This is added so that many files can reuse the function get_database()
|
# This is added so that many files can reuse the function get_database()
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# Get the database
|
# Get the database
|
||||||
dbname = get_database()
|
dbname = get_database()
|
||||||
+38
-37
@@ -1,37 +1,38 @@
|
|||||||
from flask_socketio import SocketIO
|
from flask_socketio import SocketIO
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import app_obd, time, threading
|
from modules import app_obd
|
||||||
|
import time, threading
|
||||||
socketio = SocketIO()
|
|
||||||
uptime_lock = threading.Lock()
|
socketio = SocketIO()
|
||||||
|
uptime_lock = threading.Lock()
|
||||||
@socketio.on('connect')
|
|
||||||
def connect_event():
|
@socketio.on('connect')
|
||||||
print('Client connected')
|
def connect_event():
|
||||||
print('Getting OBD status...')
|
print('Client connected')
|
||||||
app_obd.obd_connection()
|
print('Getting OBD status...')
|
||||||
uptime()
|
app_obd.obd_connection()
|
||||||
|
uptime()
|
||||||
def uptime():
|
|
||||||
thread = Thread(target=loop_uptime)
|
def uptime():
|
||||||
thread.daemon = True
|
thread = Thread(target=loop_uptime)
|
||||||
thread.start()
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
def loop_uptime():
|
|
||||||
uptime_lock.acquire()
|
def loop_uptime():
|
||||||
try:
|
uptime_lock.acquire()
|
||||||
loop = True
|
try:
|
||||||
while loop == True:
|
loop = True
|
||||||
boottime = time.clock_gettime(time.CLOCK_BOOTTIME)
|
while loop == True:
|
||||||
# Convert to hours, minutes, and seconds
|
boottime = time.clock_gettime(time.CLOCK_BOOTTIME)
|
||||||
seconds = int(boottime)
|
# Convert to hours, minutes, and seconds
|
||||||
minutes, seconds = divmod(seconds, 60)
|
seconds = int(boottime)
|
||||||
hours, minutes = divmod(minutes, 60)
|
minutes, seconds = divmod(seconds, 60)
|
||||||
time.sleep(1)
|
hours, minutes = divmod(minutes, 60)
|
||||||
uptime = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
time.sleep(1)
|
||||||
socketio.emit("rpi_uptime", uptime)
|
uptime = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
||||||
finally:
|
socketio.emit("rpi_uptime", uptime)
|
||||||
uptime_lock.release()
|
finally:
|
||||||
|
uptime_lock.release()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+21
-21
@@ -1,22 +1,22 @@
|
|||||||
from app_events import socketio
|
from modules.app_events import socketio
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
class GPS:
|
class GPS:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.LocationX = None
|
self.LocationX = None
|
||||||
self.LocationY= None
|
self.LocationY= None
|
||||||
|
|
||||||
@socketio.on('gps')
|
@socketio.on('gps')
|
||||||
def get_gps():
|
def get_gps():
|
||||||
global LocationX
|
global LocationX
|
||||||
global LocationY
|
global LocationY
|
||||||
|
|
||||||
LocationX = "45.5202844"
|
LocationX = "45.5202844"
|
||||||
LocationY = "-73.5493208"
|
LocationY = "-73.5493208"
|
||||||
Location = [LocationX, LocationY]
|
Location = [LocationX, LocationY]
|
||||||
|
|
||||||
socketio.emit('gps_location', Location)
|
socketio.emit('gps_location', Location)
|
||||||
|
|
||||||
print("websocket should be sent now")
|
print("websocket should be sent now")
|
||||||
|
|
||||||
return print("socket.io emitted")
|
return print("socket.io emitted")
|
||||||
+103
-105
@@ -1,105 +1,103 @@
|
|||||||
import obd, time, threading, app_gps, app_sql
|
from modules import app_gps, app_sql, app_events
|
||||||
from datetime import datetime
|
import obd, time, threading
|
||||||
from app_events import socketio
|
from datetime import datetime
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
status = None
|
status = None
|
||||||
speed = 0
|
speed = 0
|
||||||
rpm = None
|
rpm = None
|
||||||
|
|
||||||
class OBD:
|
class OBD:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.status = status
|
self.status = status
|
||||||
self.rpm = rpm
|
self.rpm = rpm
|
||||||
self.speed = speed
|
self.speed = speed
|
||||||
|
|
||||||
obd_status = ["Disconnected", "Connected", "Connection...", "wtf"]
|
obd_status = ["Disconnected", "Connected", "Connection...", "wtf"]
|
||||||
obd_speed_lock = threading.Lock()
|
obd_speed_lock = threading.Lock()
|
||||||
obd_rpm_lock = threading.Lock()
|
obd_rpm_lock = threading.Lock()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(obd_status[2])
|
print(obd_status[2])
|
||||||
connection = obd.OBD() # put linux /dev/rfi... something in () for the rpi bluetooth adpater
|
connection = obd.OBD() # put linux /dev/rfi... something in () for the rpi bluetooth adpater
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("An error occurred:", str(e))
|
print("An error occurred:", str(e))
|
||||||
|
|
||||||
def get_speedtime():
|
def get_speedtime():
|
||||||
global speed
|
global speed
|
||||||
date = datetime.now()
|
date = datetime.now()
|
||||||
today = str(date.today())
|
today = str(date.today())
|
||||||
time_now = str(date.strftime("%H:%M:%S"))
|
time_now = str(date.strftime("%H:%M:%S"))
|
||||||
return [str(time_now), speed]
|
return [str(time_now), speed]
|
||||||
|
|
||||||
@socketio.on('obd')
|
def obd_connection():
|
||||||
def obd_connection():
|
if connection.is_connected():
|
||||||
if connection.is_connected():
|
print(obd_status[1])
|
||||||
print(obd_status[1])
|
app_events.socketio.emit('obd_status', obd_status[1])
|
||||||
socketio.emit('obd_status', obd_status[1])
|
print("OBD connection established.")
|
||||||
print("OBD connection established.")
|
|
||||||
|
else:
|
||||||
else:
|
print("OBD connection failed.")
|
||||||
print("OBD connection failed.")
|
print(obd_status[0])
|
||||||
print(obd_status[0])
|
|
||||||
|
app_events.socketio.emit('obd_status', obd_status[0])
|
||||||
socketio.emit('obd_status', obd_status[0])
|
app_events.socketio.emit('obd_speed', "-")
|
||||||
socketio.emit('obd_speed', "-")
|
app_events.socketio.emit('obm_error', "-")
|
||||||
socketio.emit('obm_error', "-")
|
app_events.socketio.emit('obd_rpm', "-")
|
||||||
socketio.emit('obd_rpm', "-")
|
|
||||||
|
# debug speed for testing
|
||||||
# debug speed for testing
|
thread_speed = Thread(target=obd_speed)
|
||||||
thread_speed = Thread(target=obd_speed)
|
thread_speed.daemon = True
|
||||||
thread_speed.daemon = True
|
thread_speed.start()
|
||||||
thread_speed.start()
|
|
||||||
|
# debug rpm for testing
|
||||||
# debug rpm for testing
|
thread_rpm = Thread(target=obd_rpm)
|
||||||
thread_rpm = Thread(target=obd_rpm)
|
thread_rpm.daemon = True
|
||||||
thread_rpm.daemon = True
|
thread_rpm.start()
|
||||||
thread_rpm.start()
|
|
||||||
|
def obd_speed():
|
||||||
def obd_speed():
|
obd_speed_lock.acquire()
|
||||||
obd_speed_lock.acquire()
|
cmd = obd.commands.SPEED # select an OBD command (sensor)
|
||||||
cmd = obd.commands.SPEED # select an OBD command (sensor)
|
response = connection.query(cmd) # send the command and parse the response
|
||||||
response = connection.query(cmd) # send the command and parse the response
|
loop = True
|
||||||
loop = True
|
try:
|
||||||
try:
|
while loop == True:
|
||||||
while loop == True:
|
global speed
|
||||||
global speed
|
speed = speed + 1
|
||||||
speed = speed + 1
|
time.sleep(10)
|
||||||
time.sleep(10)
|
if response.is_null():
|
||||||
if response.is_null():
|
print("No data received. #"+ str(get_speedtime()))
|
||||||
print("No data received. #"+ str(get_speedtime()))
|
print(app_gps.get_gps())
|
||||||
print(app_gps.get_gps())
|
app_events.socketio.emit('obd_speed', get_speedtime())
|
||||||
socketio.emit('obd_speed', get_speedtime())
|
else:
|
||||||
app_sql.tsv_writer()
|
print("Original value:", response.value)
|
||||||
else:
|
print("Value in kph:", response.value.to("kph"))
|
||||||
print("Original value:", response.value)
|
app_events.socketio.emit('obd_speed', response.value.to("kph"))
|
||||||
print("Value in kph:", response.value.to("kph"))
|
finally:
|
||||||
socketio.emit('obd_speed', response.value.to("kph"))
|
obd_speed_lock.release()
|
||||||
finally:
|
|
||||||
obd_speed_lock.release()
|
def obd_rpm():
|
||||||
|
obd_speed_lock.acquire()
|
||||||
def obd_rpm():
|
cmd = obd.commands.RPM # select an OBD command (sensor)
|
||||||
obd_speed_lock.acquire()
|
response = connection.query(cmd) # send the command and parse the response
|
||||||
cmd = obd.commands.RPM # select an OBD command (sensor)
|
loop = True
|
||||||
response = connection.query(cmd) # send the command and parse the response
|
try:
|
||||||
loop = True
|
while loop == True:
|
||||||
try:
|
global rpm
|
||||||
while loop == True:
|
speed = speed + 1
|
||||||
global rpm
|
time.sleep(1)
|
||||||
speed = speed + 1
|
if response.is_null():
|
||||||
time.sleep(1)
|
print("No data received. #"+ str(get_speedtime()))
|
||||||
if response.is_null():
|
app_events.socketio.emit('obd_speed', get_speedtime())
|
||||||
print("No data received. #"+ str(get_speedtime()))
|
else:
|
||||||
socketio.emit('obd_speed', get_speedtime())
|
print("RPM:", response.value)
|
||||||
else:
|
app_events.socketio.emit('obd_speed', response.value.to("kph"))
|
||||||
print("RPM:", response.value)
|
finally:
|
||||||
socketio.emit('obd_speed', response.value.to("kph"))
|
obd_rpm_lock.release()
|
||||||
finally:
|
|
||||||
obd_rpm_lock.release()
|
def kill_obd(obd_type):
|
||||||
|
if obd_type == "speed":
|
||||||
def kill_obd(obd_type):
|
obd_speed.loop = False
|
||||||
if obd_type == "speed":
|
elif obd_type == "rpm":
|
||||||
obd_speed.loop = False
|
obd_rpm.loop = False
|
||||||
elif obd_type == "rpm":
|
|
||||||
obd_rpm.loop = False
|
|
||||||
|
|||||||
+77
-77
@@ -1,78 +1,78 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import app_obd, app_car, app_account, app_gps
|
from modules import app_obd, app_car, app_account, app_gps
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlite3 import Error
|
from sqlite3 import Error
|
||||||
|
|
||||||
currentdatetime = datetime.now()
|
currentdatetime = datetime.now()
|
||||||
account = app_account.Account
|
account = app_account.Account()
|
||||||
car = app_car.Car
|
car = app_car.Car()
|
||||||
sCarModel = ''.join(letter for letter in car.model if letter.isalnum())
|
sCarModel = ''.join(letter for letter in car.model if letter.isalnum())
|
||||||
sql_file = account.name + "_" + sCarModel + ".db"
|
sql_file = account.name + "_" + sCarModel + ".db"
|
||||||
sql_path = "../db/sql/" + sql_file
|
sql_path = "../db/sql/" + sql_file
|
||||||
|
|
||||||
def create_conn(db_file):
|
def create_conn(db_file):
|
||||||
conn = None
|
conn = None
|
||||||
try:
|
try:
|
||||||
conn = sqlite3.connect(db_file)
|
conn = sqlite3.connect(db_file)
|
||||||
print(sqlite3.version)
|
print(sqlite3.version)
|
||||||
except Error as e:
|
except Error as e:
|
||||||
print(e)
|
print(e)
|
||||||
finally:
|
finally:
|
||||||
if conn:
|
if conn:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def create_table(conn, create_table_sql):
|
def create_table(conn, create_table_sql):
|
||||||
""" create a table from the create_table_sql statement
|
""" create a table from the create_table_sql statement
|
||||||
:param conn: Connection object
|
:param conn: Connection object
|
||||||
:param create_table_sql: a CREATE TABLE statement
|
:param create_table_sql: a CREATE TABLE statement
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute(create_table_sql)
|
c.execute(create_table_sql)
|
||||||
except Error as e:
|
except Error as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
db = sql_path
|
db = sql_path
|
||||||
|
|
||||||
sql_create_tracking_table = """CREATE TABLE IF NOT EXISTS tracking (
|
sql_create_tracking_table = """CREATE TABLE IF NOT EXISTS tracking (
|
||||||
id integer PRIMARY KEY,
|
id integer PRIMARY KEY,
|
||||||
VN text NOT NULL,
|
VN text NOT NULL,
|
||||||
NAME text NOT NULL,
|
NAME text NOT NULL,
|
||||||
DATETIME datetime,
|
DATETIME datetime,
|
||||||
GPSX float,
|
GPSX float,
|
||||||
GPSY float,
|
GPSY float,
|
||||||
SPEED float,
|
SPEED float,
|
||||||
ODOMETER float
|
ODOMETER float
|
||||||
);"""
|
);"""
|
||||||
|
|
||||||
sql_create_dtc_table = """CREATE TABLE IF NOT EXISTS dtc (
|
sql_create_dtc_table = """CREATE TABLE IF NOT EXISTS dtc (
|
||||||
id integer PRIMARY KEY,
|
id integer PRIMARY KEY,
|
||||||
NAME text NOT NULL,
|
NAME text NOT NULL,
|
||||||
STATUS text,
|
STATUS text,
|
||||||
DTC_ID text
|
DTC_ID text
|
||||||
);"""
|
);"""
|
||||||
|
|
||||||
# create a database connection
|
# create a database connection
|
||||||
conn = create_conn(db)
|
conn = create_conn(db)
|
||||||
|
|
||||||
# create tables
|
# create tables
|
||||||
if conn is not None:
|
if conn is not None:
|
||||||
# create diagnostics table
|
# create diagnostics table
|
||||||
create_table(conn, sql_create_tracking_table)
|
create_table(conn, sql_create_tracking_table)
|
||||||
|
|
||||||
# create diagnostics table
|
# create diagnostics table
|
||||||
create_table(conn, sql_create_dtc_table)
|
create_table(conn, sql_create_dtc_table)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Error! cannot create the database connection.")
|
print("Error! cannot create the database connection.")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
create_conn(sql_path)
|
create_conn(sql_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ## VN, NAME, DATE, TIME, GPS_X, GPS_Y, SPEED, ODOMETER
|
# ## VN, NAME, DATE, TIME, GPS_X, GPS_Y, SPEED, ODOMETER
|
||||||
# (["VN", "NAME", "DATE", "TIME", "GPSX", "GPSY", "SPEED", "ODOMETER"])
|
# (["VN", "NAME", "DATE", "TIME", "GPSX", "GPSY", "SPEED", "ODOMETER"])
|
||||||
# ([car.model, account.name, currentday, currenttime, GPSX, GPSY, SPEED, ODOMETER])
|
# ([car.model, account.name, currentday, currenttime, GPSX, GPSY, SPEED, ODOMETER])
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# yaris-obd #
|
# yaris-obd #
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
python3 app.py
|
python3 app.py
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
Flask
|
Flask
|
||||||
Flask-SocketIO
|
Flask-SocketIO
|
||||||
gevent
|
gevent
|
||||||
pymongo
|
pymongo
|
||||||
python-dotenv
|
python-dotenv
|
||||||
+6
-6
File diff suppressed because one or more lines are too long
Vendored
+6
-6
File diff suppressed because one or more lines are too long
+3535
-3535
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 692 KiB After Width: | Height: | Size: 696 KiB |
+803
-803
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 142 KiB |
+4700
-4700
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 829 KiB After Width: | Height: | Size: 834 KiB |
Vendored
+4
-4
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
var charts = document.querySelectorAll('[data-bss-chart]');
|
var charts = document.querySelectorAll('[data-bss-chart]');
|
||||||
|
|
||||||
for (var chart of charts) {
|
for (var chart of charts) {
|
||||||
chart.chart = new Chart(chart, JSON.parse(chart.dataset.bssChart));
|
chart.chart = new Chart(chart, JSON.parse(chart.dataset.bssChart));
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
Vendored
+7
-7
File diff suppressed because one or more lines are too long
+76
-76
@@ -1,76 +1,76 @@
|
|||||||
(function() {
|
(function() {
|
||||||
"use strict"; // Start of use strict
|
"use strict"; // Start of use strict
|
||||||
|
|
||||||
var sidebar = document.querySelector('.sidebar');
|
var sidebar = document.querySelector('.sidebar');
|
||||||
var sidebarToggles = document.querySelectorAll('#sidebarToggle, #sidebarToggleTop');
|
var sidebarToggles = document.querySelectorAll('#sidebarToggle, #sidebarToggleTop');
|
||||||
|
|
||||||
if (sidebar) {
|
if (sidebar) {
|
||||||
|
|
||||||
var collapseEl = sidebar.querySelector('.collapse');
|
var collapseEl = sidebar.querySelector('.collapse');
|
||||||
var collapseElementList = [].slice.call(document.querySelectorAll('.sidebar .collapse'))
|
var collapseElementList = [].slice.call(document.querySelectorAll('.sidebar .collapse'))
|
||||||
var sidebarCollapseList = collapseElementList.map(function (collapseEl) {
|
var sidebarCollapseList = collapseElementList.map(function (collapseEl) {
|
||||||
return new bootstrap.Collapse(collapseEl, { toggle: false });
|
return new bootstrap.Collapse(collapseEl, { toggle: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var toggle of sidebarToggles) {
|
for (var toggle of sidebarToggles) {
|
||||||
|
|
||||||
// Toggle the side navigation
|
// Toggle the side navigation
|
||||||
toggle.addEventListener('click', function(e) {
|
toggle.addEventListener('click', function(e) {
|
||||||
document.body.classList.toggle('sidebar-toggled');
|
document.body.classList.toggle('sidebar-toggled');
|
||||||
sidebar.classList.toggle('toggled');
|
sidebar.classList.toggle('toggled');
|
||||||
|
|
||||||
if (sidebar.classList.contains('toggled')) {
|
if (sidebar.classList.contains('toggled')) {
|
||||||
for (var bsCollapse of sidebarCollapseList) {
|
for (var bsCollapse of sidebarCollapseList) {
|
||||||
bsCollapse.hide();
|
bsCollapse.hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close any open menu accordions when window is resized below 768px
|
// Close any open menu accordions when window is resized below 768px
|
||||||
window.addEventListener('resize', function() {
|
window.addEventListener('resize', function() {
|
||||||
var vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
var vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
||||||
|
|
||||||
if (vw < 768) {
|
if (vw < 768) {
|
||||||
for (var bsCollapse of sidebarCollapseList) {
|
for (var bsCollapse of sidebarCollapseList) {
|
||||||
bsCollapse.hide();
|
bsCollapse.hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent the content wrapper from scrolling when the fixed side navigation hovered over
|
// Prevent the content wrapper from scrolling when the fixed side navigation hovered over
|
||||||
|
|
||||||
var fixedNaigation = document.querySelector('body.fixed-nav .sidebar');
|
var fixedNaigation = document.querySelector('body.fixed-nav .sidebar');
|
||||||
|
|
||||||
if (fixedNaigation) {
|
if (fixedNaigation) {
|
||||||
fixedNaigation.on('mousewheel DOMMouseScroll wheel', function(e) {
|
fixedNaigation.on('mousewheel DOMMouseScroll wheel', function(e) {
|
||||||
var vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
var vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
||||||
|
|
||||||
if (vw > 768) {
|
if (vw > 768) {
|
||||||
var e0 = e.originalEvent,
|
var e0 = e.originalEvent,
|
||||||
delta = e0.wheelDelta || -e0.detail;
|
delta = e0.wheelDelta || -e0.detail;
|
||||||
this.scrollTop += (delta < 0 ? 1 : -1) * 30;
|
this.scrollTop += (delta < 0 ? 1 : -1) * 30;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrollToTop = document.querySelector('.scroll-to-top');
|
var scrollToTop = document.querySelector('.scroll-to-top');
|
||||||
|
|
||||||
if (scrollToTop) {
|
if (scrollToTop) {
|
||||||
|
|
||||||
// Scroll to top button appear
|
// Scroll to top button appear
|
||||||
window.addEventListener('scroll', function() {
|
window.addEventListener('scroll', function() {
|
||||||
var scrollDistance = window.pageYOffset;
|
var scrollDistance = window.pageYOffset;
|
||||||
|
|
||||||
//check if user is scrolling up
|
//check if user is scrolling up
|
||||||
if (scrollDistance > 100) {
|
if (scrollDistance > 100) {
|
||||||
scrollToTop.style.display = 'block';
|
scrollToTop.style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
scrollToTop.style.display = 'none';
|
scrollToTop.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
})(); // End of use strict
|
})(); // End of use strict
|
||||||
|
|||||||
+104
-104
@@ -1,105 +1,105 @@
|
|||||||
const socket = io();
|
const socket = io();
|
||||||
// map
|
// map
|
||||||
|
|
||||||
var map = L.map('map').setView([48.505, -0.09], 13);
|
var map = L.map('map').setView([48.505, -0.09], 13);
|
||||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
L.marker([51.5, -0.09]).addTo(map)
|
L.marker([51.5, -0.09]).addTo(map)
|
||||||
.bindPopup('your car... soon(tm)')
|
.bindPopup('your car... soon(tm)')
|
||||||
.openPopup();
|
.openPopup();
|
||||||
|
|
||||||
// charts
|
// charts
|
||||||
|
|
||||||
const ctx = document.getElementById('speedGraph').getContext('2d');
|
const ctx = document.getElementById('speedGraph').getContext('2d');
|
||||||
chart = new Chart(ctx, {
|
chart = new Chart(ctx, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Vehicle speed',
|
label: 'Vehicle speed',
|
||||||
borderColor: 'rgba(75, 192, 192, 1)',
|
borderColor: 'rgba(75, 192, 192, 1)',
|
||||||
fill: false,
|
fill: false,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
reverse: true,
|
reverse: true,
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Time',
|
text: 'Time',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Speed'
|
text: 'Speed'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// websockets
|
// websockets
|
||||||
|
|
||||||
socket.on('connect', function(data) {
|
socket.on('connect', function(data) {
|
||||||
console.log('socket.io is connected')
|
console.log('socket.io is connected')
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('obd_status', function(data) {
|
socket.on('obd_status', function(data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
const status = document.getElementById('obd-status');
|
const status = document.getElementById('obd-status');
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('obd_speed', function(data) {
|
socket.on('obd_speed', function(data) {
|
||||||
|
|
||||||
const time = data[0]; // Assuming data[0] is the time value
|
const time = data[0]; // Assuming data[0] is the time value
|
||||||
const speed = data[1]; // Assuming data[1] is the speed value
|
const speed = data[1]; // Assuming data[1] is the speed value
|
||||||
const maxDataPoints = 8; // Adjust this value as needed
|
const maxDataPoints = 8; // Adjust this value as needed
|
||||||
|
|
||||||
const status = document.getElementById('obd-speed');
|
const status = document.getElementById('obd-speed');
|
||||||
status.innerHTML = speed;
|
status.innerHTML = speed;
|
||||||
|
|
||||||
// Get a reference to the chart's data
|
// Get a reference to the chart's data
|
||||||
const chartData = chart.data.datasets[0].data;
|
const chartData = chart.data.datasets[0].data;
|
||||||
|
|
||||||
// Unshift the new data points to the beginning of the chart dataset
|
// Unshift the new data points to the beginning of the chart dataset
|
||||||
chartData.unshift({ x: time, y: speed });
|
chartData.unshift({ x: time, y: speed });
|
||||||
|
|
||||||
// Remove data points if the number of data points exceeds maxDataPoints
|
// Remove data points if the number of data points exceeds maxDataPoints
|
||||||
while (chartData.length > maxDataPoints) {
|
while (chartData.length > maxDataPoints) {
|
||||||
chartData.pop(); // Remove the oldest data point from the end
|
chartData.pop(); // Remove the oldest data point from the end
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the chart
|
// Update the chart
|
||||||
chart.update();
|
chart.update();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('obd_rpm', function(data) {
|
socket.on('obd_rpm', function(data) {
|
||||||
console.log("obd rpm "+data);
|
console.log("obd rpm "+data);
|
||||||
const status = document.getElementById('obd-rpm');
|
const status = document.getElementById('obd-rpm');
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('obd_error', function(data) {
|
socket.on('obd_error', function(data) {
|
||||||
console.log("obd errors "+data);
|
console.log("obd errors "+data);
|
||||||
const status = document.getElementById('obd-error');
|
const status = document.getElementById('obd-error');
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('rpi_uptime', function(data) {
|
socket.on('rpi_uptime', function(data) {
|
||||||
const status = document.getElementById('rpi-uptime');
|
const status = document.getElementById('rpi-uptime');
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('gps_location', function(data) {
|
socket.on('gps_location', function(data) {
|
||||||
console.log("location received")
|
console.log("location received")
|
||||||
const LocationX = document.getElementById('gpsLocationX');
|
const LocationX = document.getElementById('gpsLocationX');
|
||||||
const LocationY = document.getElementById('gpsLocationY');
|
const LocationY = document.getElementById('gpsLocationY');
|
||||||
LocationX.innerHTML = data[0];
|
LocationX.innerHTML = data[0];
|
||||||
LocationY.innerHTML = data[1];
|
LocationY.innerHTML = data[1];
|
||||||
|
|
||||||
});
|
});
|
||||||
+82
-82
@@ -1,83 +1,83 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-bs-theme="light" lang="en">
|
<html data-bs-theme="light" lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>Dashboard - yaris vroom vroom de course</title>
|
<title>Dashboard - yaris vroom vroom de course</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="page-top">
|
<body id="page-top">
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
||||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
||||||
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
||||||
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
||||||
</a>
|
</a>
|
||||||
<hr class="sidebar-divider my-0">
|
<hr class="sidebar-divider my-0">
|
||||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link active" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
<li class="nav-item"><a class="nav-link active" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper">
|
<div class="d-flex flex-column" id="content-wrapper">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
||||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||||
<div class="input-group"></div>
|
<div class="input-group"></div>
|
||||||
</form>
|
</form>
|
||||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||||
<form class="me-auto navbar-search w-100">
|
<form class="me-auto navbar-search w-100">
|
||||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
||||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<div class="d-none d-sm-block topbar-divider"></div>
|
<div class="d-none d-sm-block topbar-divider"></div>
|
||||||
<li class="nav-item dropdown no-arrow">
|
<li class="nav-item dropdown no-arrow">
|
||||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="shadow dropdown-list dropdown-menu dropdown-menu-end" aria-labelledby="alertsDropdown"></div>
|
<div class="shadow dropdown-list dropdown-menu dropdown-menu-end" aria-labelledby="alertsDropdown"></div>
|
||||||
</li>
|
</li>
|
||||||
<div class="d-none d-sm-block topbar-divider"></div>
|
<div class="d-none d-sm-block topbar-divider"></div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<h3 class="text-dark mb-4">DTC Codes</h3>
|
<h3 class="text-dark mb-4">DTC Codes</h3>
|
||||||
<div class="card shadow">
|
<div class="card shadow">
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
<p class="text-primary m-0 fw-bold">Output</p>
|
<p class="text-primary m-0 fw-bold">Output</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body"></div>
|
<div class="card-body"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer class="bg-white sticky-footer">
|
<footer class="bg-white sticky-footer">
|
||||||
<div class="container my-auto">
|
<div class="container my-auto">
|
||||||
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+82
-82
@@ -1,83 +1,83 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-bs-theme="light" lang="en">
|
<html data-bs-theme="light" lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>Dashboard - yaris vroom vroom de course</title>
|
<title>Dashboard - yaris vroom vroom de course</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="page-top">
|
<body id="page-top">
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
||||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
||||||
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
||||||
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
||||||
</a>
|
</a>
|
||||||
<hr class="sidebar-divider my-0">
|
<hr class="sidebar-divider my-0">
|
||||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link active" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
<li class="nav-item"><a class="nav-link active" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper">
|
<div class="d-flex flex-column" id="content-wrapper">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
||||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||||
<div class="input-group"></div>
|
<div class="input-group"></div>
|
||||||
</form>
|
</form>
|
||||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||||
<form class="me-auto navbar-search w-100">
|
<form class="me-auto navbar-search w-100">
|
||||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
||||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<div class="d-none d-sm-block topbar-divider"></div>
|
<div class="d-none d-sm-block topbar-divider"></div>
|
||||||
<li class="nav-item dropdown no-arrow">
|
<li class="nav-item dropdown no-arrow">
|
||||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="shadow dropdown-list dropdown-menu dropdown-menu-end" aria-labelledby="alertsDropdown"></div>
|
<div class="shadow dropdown-list dropdown-menu dropdown-menu-end" aria-labelledby="alertsDropdown"></div>
|
||||||
</li>
|
</li>
|
||||||
<div class="d-none d-sm-block topbar-divider"></div>
|
<div class="d-none d-sm-block topbar-divider"></div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<h3 class="text-dark mb-4">DTC Codes</h3>
|
<h3 class="text-dark mb-4">DTC Codes</h3>
|
||||||
<div class="card shadow">
|
<div class="card shadow">
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
<p class="text-primary m-0 fw-bold">Output</p>
|
<p class="text-primary m-0 fw-bold">Output</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body"></div>
|
<div class="card-body"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer class="bg-white sticky-footer">
|
<footer class="bg-white sticky-footer">
|
||||||
<div class="container my-auto">
|
<div class="container my-auto">
|
||||||
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+190
-190
@@ -1,191 +1,191 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-bs-theme="light" lang="en">
|
<html data-bs-theme="light" lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>Dashboard - yaris vroom vroom de course</title>
|
<title>Dashboard - yaris vroom vroom de course</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='yaris.css') }}">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i&display=swap">
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="page-top">
|
<body id="page-top">
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark" style="color: var(--bs-accordion-btn-focus-border-color);background: rgb(0,0,0);filter: blur(0px);backdrop-filter: blur(0px) hue-rotate(0deg);">
|
||||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
|
||||||
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-car"></i></div>
|
||||||
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
<div id="index-car-model" class="sidebar-brand-text mx-3"><span>{{ car.model }}</span></div>
|
||||||
</a>
|
</a>
|
||||||
<hr class="sidebar-divider my-0">
|
<hr class="sidebar-divider my-0">
|
||||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||||
<li class="nav-item"><a class="nav-link active" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
<li class="nav-item"><a class="nav-link active" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/dash"><i class="fas fa-table"></i><span>Dashcam </span></a></li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/dtc"><i class="fas fa-table"></i><span>DTC </span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper">
|
<div class="d-flex flex-column" id="content-wrapper">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
<nav class="navbar navbar-expand bg-white shadow mb-4 topbar static-top navbar-light">
|
||||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||||
<div class="input-group"></div>
|
<div class="input-group"></div>
|
||||||
</form>
|
</form>
|
||||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||||
<form class="me-auto navbar-search w-100">
|
<form class="me-auto navbar-search w-100">
|
||||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
||||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<div class="d-none d-sm-block topbar-divider"></div>
|
<div class="d-none d-sm-block topbar-divider"></div>
|
||||||
<li class="nav-item dropdown no-arrow">
|
<li class="nav-item dropdown no-arrow">
|
||||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span id="index-pp" class="d-none d-lg-inline me-2 text-gray-600 small">{{ account.name }}</span><img class="border rounded-circle img-profile" src="{{ url_for('static', filename='img/yaris.png') }}"></a>
|
||||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="#"><i class="fas fa-user fa-sm fa-fw me-2 text-gray-400"></i> Profile</a><a class="dropdown-item" href="#"><i class="fas fa-cogs fa-sm fa-fw me-2 text-gray-400"></i> Settings</a><a class="dropdown-item" href="#"><i class="fas fa-list fa-sm fa-fw me-2 text-gray-400"></i> Activity log</a>
|
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="#"><i class="fas fa-user fa-sm fa-fw me-2 text-gray-400"></i> Profile</a><a class="dropdown-item" href="#"><i class="fas fa-cogs fa-sm fa-fw me-2 text-gray-400"></i> Settings</a><a class="dropdown-item" href="#"><i class="fas fa-list fa-sm fa-fw me-2 text-gray-400"></i> Activity log</a>
|
||||||
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a>
|
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="d-sm-flex justify-content-between align-items-center mb-4">
|
<div class="d-sm-flex justify-content-between align-items-center mb-4">
|
||||||
<h3 class="text-dark mb-0">Dashboard</h3><a class="btn btn-primary btn-sm d-none d-sm-inline-block" role="button" href="#"><i class="fas fa-download fa-sm text-white-50"></i> Placeholder button</a>
|
<h3 class="text-dark mb-0">Dashboard</h3><a class="btn btn-primary btn-sm d-none d-sm-inline-block" role="button" href="#"><i class="fas fa-download fa-sm text-white-50"></i> Placeholder button</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-xl-3 mb-4">
|
<div class="col-md-6 col-xl-3 mb-4">
|
||||||
<div class="card shadow border-start-primary py-2">
|
<div class="card shadow border-start-primary py-2">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center no-gutters">
|
<div class="row align-items-center no-gutters">
|
||||||
<div class="col me-2">
|
<div class="col me-2">
|
||||||
<div class="text-uppercase text-primary fw-bold text-xs mb-1"><span>OBD Status</span></div>
|
<div class="text-uppercase text-primary fw-bold text-xs mb-1"><span>OBD Status</span></div>
|
||||||
<div id="obd-status" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
<div id="obd-status" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto"><i class="fas fa-calendar fa-2x text-gray-300"></i></div>
|
<div class="col-auto"><i class="fas fa-calendar fa-2x text-gray-300"></i></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-3 mb-4">
|
<div class="col-md-6 col-xl-3 mb-4">
|
||||||
<div class="card shadow border-start-success py-2">
|
<div class="card shadow border-start-success py-2">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center no-gutters">
|
<div class="row align-items-center no-gutters">
|
||||||
<div class="col me-2">
|
<div class="col me-2">
|
||||||
<div class="text-uppercase text-success fw-bold text-xs mb-1"><span>VEHICLE SPEED</span></div>
|
<div class="text-uppercase text-success fw-bold text-xs mb-1"><span>VEHICLE SPEED</span></div>
|
||||||
<div id="obd-speed" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
<div id="obd-speed" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto"><i class="fas fa-dollar-sign fa-2x text-gray-300"></i></div>
|
<div class="col-auto"><i class="fas fa-dollar-sign fa-2x text-gray-300"></i></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-3 mb-4">
|
<div class="col-md-6 col-xl-3 mb-4">
|
||||||
<div class="card shadow border-start-info py-2">
|
<div class="card shadow border-start-info py-2">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center no-gutters">
|
<div class="row align-items-center no-gutters">
|
||||||
<div class="col me-2">
|
<div class="col me-2">
|
||||||
<div class="text-uppercase text-warning fw-bold text-xs mb-1" style="color: rgb(246,62,62);"><span style="color: rgb(246,62,62);">RPM</span></div>
|
<div class="text-uppercase text-warning fw-bold text-xs mb-1" style="color: rgb(246,62,62);"><span style="color: rgb(246,62,62);">RPM</span></div>
|
||||||
<div id="obd-rpm" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
<div id="obd-rpm" class="text-dark fw-bold h5 mb-0"><span>unknown</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto"><i class="fas fa-comments fa-2x text-gray-300"></i></div>
|
<div class="col-auto"><i class="fas fa-comments fa-2x text-gray-300"></i></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-3 mb-4">
|
<div class="col-md-6 col-xl-3 mb-4">
|
||||||
<div class="card shadow border-start-warning py-2">
|
<div class="card shadow border-start-warning py-2">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center no-gutters">
|
<div class="row align-items-center no-gutters">
|
||||||
<div class="col me-2">
|
<div class="col me-2">
|
||||||
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>UPTIME</span></div>
|
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>UPTIME</span></div>
|
||||||
<div class="row g-0 align-items-center">
|
<div class="row g-0 align-items-center">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<div id="rpi-uptime" class="text-dark fw-bold h5 mb-0 me-3"><span>unknown</span></div>
|
<div id="rpi-uptime" class="text-dark fw-bold h5 mb-0 me-3"><span>unknown</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto"><i class="fas fa-clipboard-list fa-2x text-gray-300"></i></div>
|
<div class="col-auto"><i class="fas fa-clipboard-list fa-2x text-gray-300"></i></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-7 col-xl-8">
|
<div class="col-lg-7 col-xl-8">
|
||||||
<div class="card shadow mb-4">
|
<div class="card shadow mb-4">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-primary fw-bold m-0">Speed Graph</h6>
|
<h6 class="text-primary fw-bold m-0">Speed Graph</h6>
|
||||||
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
||||||
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
||||||
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
||||||
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="chart-container" style="position: relative; height:40vh; text-align: center;">
|
<div class="chart-container" style="position: relative; height:40vh; text-align: center;">
|
||||||
<canvas id="speedGraph"></canvas>
|
<canvas id="speedGraph"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-5 col-xl-4">
|
<div class="col-lg-5 col-xl-4">
|
||||||
<div class="card shadow mb-4">
|
<div class="card shadow mb-4">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-primary fw-bold m-0">GPS</h6>
|
<h6 class="text-primary fw-bold m-0">GPS</h6>
|
||||||
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
||||||
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
||||||
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
||||||
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card shadow mb-4">
|
<div class="card shadow mb-4">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-primary fw-bold m-0">GPS Info</h6>
|
<h6 class="text-primary fw-bold m-0">GPS Info</h6>
|
||||||
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
<div class="dropdown no-arrow"><button class="btn btn-link btn-sm dropdown-toggle" aria-expanded="false" data-bs-toggle="dropdown" type="button"><i class="fas fa-ellipsis-v text-gray-400"></i></button>
|
||||||
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
<div class="dropdown-menu shadow dropdown-menu-end animated--fade-in">
|
||||||
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
<p class="text-center dropdown-header">dropdown header:</p><a class="dropdown-item" href="#"> Action</a><a class="dropdown-item" href="#"> Another action</a>
|
||||||
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
<div class="dropdown-divider"></div><a class="dropdown-item" href="#"> Something else here</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>GPS X: <span id="gpsLocationX"></span></p>
|
<p>GPS X: <span id="gpsLocationX"></span></p>
|
||||||
<p>GPS Y: <span id="gpsLocationY"></span></p>
|
<p>GPS Y: <span id="gpsLocationY"></span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer class="bg-white sticky-footer">
|
<footer class="bg-white sticky-footer">
|
||||||
<div class="container my-auto">
|
<div class="container my-auto">
|
||||||
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
<div class="text-center my-auto copyright"><span>Copyright © yaris vroom vroom de course 2023</span></div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
</div><a class="border rounded d-inline scroll-to-top" href="#page-top"><i class="fas fa-angle-up"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script>
|
||||||
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||||
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user