PHD Project - Driver energy prediction
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

480 lines
26 KiB

2 years ago
# Title: CARIAD-Routing GUI
# Author: Johannes Ziegmann
# Mail: johannes.ziegmann@cariad.technology
# Date: 10.12.2021
# Description: CARIAD-Routing GUI for showing the request details graphically distributed on map
import sys
import os
import requests
import config as cfg
import time
import gmplot
import datetime
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
# Creating the main window
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'CARIAD Routing'
self.setWindowTitle(self.title)
self.setGeometry(250, 250, 1050, 1000)
self.tab_widget = MyTabWidget(self)
self.setCentralWidget(self.tab_widget)
self.show()
# Creating tab widgets
class MyTabWidget(QWidget):
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
# Initialize tab screen
self.tabs = QTabWidget()
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab1UI()
self.tab2UI()
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
def tab1UI(self):
self.tabs.addTab(self.tab1, "Map")
self.pushButton_setStart = QPushButton()
self.pushButton_setStart.setGeometry(QtCore.QRect(10, 10, 250, 30))
self.pushButton_setStart.setFixedSize(250,30)
self.pushButton_setStart.setObjectName("pushButton_setStart")
self.pushButton_setStart.clicked.connect(self.setStart)
self.pushButton_setStart.setText("set ccp")
self.pushButton_setDestination = QPushButton()
self.pushButton_setDestination.setGeometry(QtCore.QRect(10, 50, 250, 30))
self.pushButton_setDestination.setFixedSize(250,30)
self.pushButton_setDestination.setObjectName("pushButton_setDestination")
self.pushButton_setDestination.clicked.connect(self.setDestination)
self.pushButton_setDestination.setText("set Destination")
self.label_map = QWebEngineView(self.tab1)#(ui.centralwidget)
self.label_map.setGeometry(QtCore.QRect(10, 90, 1010, 860))
local_url = QUrl.fromLocalFile(os.path.abspath("./figures/map.html"))
self.label_map.load(local_url)
self.label_map.setWindowTitle('QWebEngineView')
self.label_map.show()
self.label_map.setZoomFactor(1.4)
hbox = QHBoxLayout()
vbox = QVBoxLayout()
vbox.addWidget(self.pushButton_setStart)
vbox.addWidget(self.pushButton_setDestination)
vbox.addWidget(self.label_map)
self.tab1.setLayout(vbox)
def tab2UI(self):
self.tabs.addTab(self.tab2, "Vehicle")
self.textEdit_vehicle = QTextEdit()
self.textEdit_vehicle.setGeometry(QtCore.QRect(20, 10, 200, 30))
self.textEdit_vehicle.setFixedSize(200,30)
self.textEdit_vehicle.setObjectName("textEdit_vehicle")
self.textEdit_vehicle.setPlaceholderText('not editable')
self.textEdit_vehicle.setReadOnly(True)
self.textEdit_vehicleData = QTextEdit()
self.textEdit_vehicleData.setGeometry(QtCore.QRect(20, 50, 200, 30))
self.textEdit_vehicleData.setFixedSize(200,30)
self.textEdit_vehicleData.setObjectName("textEdit_vehicleData")
self.textEdit_vehicleData.setPlaceholderText('Vehicle Data (model ID)')
self.textEdit_vehicleData.setText('M1J')
self.textEdit_consumptionData = QTextEdit()
self.textEdit_consumptionData.setGeometry(QtCore.QRect(20, 90, 200, 30))
self.textEdit_consumptionData.setFixedSize(200,30)
self.textEdit_consumptionData.setObjectName("textEdit_consumptionData")
self.textEdit_consumptionData.setPlaceholderText('Vehicle Data (model code)')
self.textEdit_consumptionData.setText('GEN')
self.pushButton_showVehicles = QPushButton()
self.pushButton_showVehicles.setGeometry(QtCore.QRect(260, 10, 200, 30))
self.pushButton_showVehicles.setFixedSize(200,30)
self.pushButton_showVehicles.setObjectName("pushButton_calculateRoute")
self.pushButton_showVehicles.clicked.connect(self.showVehicle)
self.pushButton_showVehicles.setText("show vehicles")
self.pushButton_showVehicleData = QPushButton()
self.pushButton_showVehicleData.setGeometry(QtCore.QRect(260, 50, 200, 30))
self.pushButton_showVehicleData.setFixedSize(200,30)
self.pushButton_showVehicleData.setObjectName("pushButton_showVehicleData")
self.pushButton_showVehicleData.clicked.connect(self.showVehicleData)
self.pushButton_showVehicleData.setText("show vehicle data")
self.pushButton_showConsumptionData = QPushButton()
self.pushButton_showConsumptionData.setGeometry(QtCore.QRect(260, 90, 200, 30))
self.pushButton_showConsumptionData.setFixedSize(200,30)
self.pushButton_showConsumptionData.setObjectName("pushButton_showConsumptionData")
self.pushButton_showConsumptionData.clicked.connect(self.showConsumptionData)
self.pushButton_showConsumptionData.setText("show vehicles")
self.pushButton_clear_label_showVhicleData = QPushButton()
self.pushButton_clear_label_showVhicleData.setFixedSize(106,106)
self.pushButton_clear_label_showVhicleData.setObjectName("pushButton_clear_label_showVhicleData")
self.pushButton_clear_label_showVhicleData.clicked.connect(self.clear_label_showVhicleData)
self.pushButton_clear_label_showVhicleData.setText("clear")
self.label_showVehicleData = QTextBrowser()
self.label_showVehicleData.setObjectName("label_showVehicleData")
#self.label_showVehicleData.setText("response time [s]:")
hbox = QHBoxLayout()
vbox = QVBoxLayout()
vbox.addWidget(self.textEdit_vehicle)
vbox.addWidget(self.textEdit_vehicleData)
vbox.addWidget(self.textEdit_consumptionData)
hbox.addLayout(vbox)
vbox = QVBoxLayout()
vbox.addWidget(self.pushButton_showVehicles)
vbox.addWidget(self.pushButton_showVehicleData)
vbox.addWidget(self.pushButton_showConsumptionData)
hbox.addLayout(vbox)
hbox.addWidget(self.pushButton_clear_label_showVhicleData)
hbox.addStretch(0)
vbox = QVBoxLayout()
vbox.addLayout(hbox)
vbox.addWidget(self.label_showVehicleData)
self.tab2.setLayout(vbox)
def clear_label_showVhicleData(self):
self.label_showVehicleData.clear()
def showVehicle(self):
try:
# updateBearerToken
url = "https://oidc.car-cloud.org/auth/realms/OEM/protocol/openid-connect/token"
par = { "grant_type" : "client_credentials",
"client_id":"etron-rp",
"client_secret":"e7b479bf-df6e-4513-9565-0283d5873f50",
}
start = time.perf_counter()
response = requests.post(url,data=par,timeout=300).json()
request_time_token = time.perf_counter() - start
print('time get token: %s sec'%str(round(request_time_token,3)))
ac_token = response['access_token']
url_cs = "https://cariad-routing.tui.car-cloud.org/vehicles"
print(url_cs)
head = {
'Authorization': 'Bearer ' + ac_token
}
start = time.perf_counter()
response = requests.get(url_cs,headers=head,timeout=300)
request_time = round(time.perf_counter() - start,3)
#print('DateTime: %s\nReqest time: %s\nRespones URL: %s\nResponse: %s\n#######################\n\n'%(str(datetime.datetime.now()),str(request_time),str(response.url),str(response)))
self.label_showVehicleData.append('### show vehicle ###')
self.label_showVehicleData.append('DateTime: '+str(datetime.datetime.now()))
self.label_showVehicleData.append('Reqest time: '+str(request_time))
self.label_showVehicleData.append('Respones URL: '+str(response.url))
try:
self.label_showVehicleData.append('Response: '+str(response.json()))
except:
print('ERROR: sevice not reachable')
self.label_showVehicleData.append('Response: '+str(response))
self.label_showVehicleData.append('############################################')
except Exception as e:
print("ERROR : "+str(e))
def showVehicleData(self):
try:
# updateBearerToken
url = "https://oidc.car-cloud.org/auth/realms/OEM/protocol/openid-connect/token"
par = { "grant_type" : "client_credentials",
"client_id":"etron-rp",
"client_secret":"e7b479bf-df6e-4513-9565-0283d5873f50",
}
start = time.perf_counter()
response = requests.post(url,data=par,timeout=300).json()
request_time_token = time.perf_counter() - start
print('time get token: %s sec'%str(round(request_time_token,3)))
ac_token = response['access_token']
url_cs = "https://cariad-routing.tui.car-cloud.org/vehicleData?"
print(url_cs)
parameter = { "modelId":(self.textEdit_vehicleData.toPlainText()),
}
head = {
'Authorization': 'Bearer ' + ac_token
}
start = time.perf_counter()
response = requests.get(url_cs,params=parameter,headers=head,timeout=300)
request_time = round(time.perf_counter() - start,3)
#print('DateTime: %s\nReqest time: %s\nRespones URL: %s\nResponse: %s\n#######################\n\n'%(str(datetime.datetime.now()),str(request_time),str(response.url),str(response)))
self.label_showVehicleData.append('### show vehicle data ###')
self.label_showVehicleData.append('DateTime: '+str(datetime.datetime.now()))
self.label_showVehicleData.append('Reqest time: '+str(request_time))
self.label_showVehicleData.append('Respones URL: '+str(response.url))
try:
self.label_showVehicleData.append('Response: '+str(response.json()))
except:
print('ERROR: sevice not reachable')
self.label_showVehicleData.append('Response: '+str(response))
self.label_showVehicleData.append('############################################')
except Exception as e:
print("ERROR : "+str(e))
def showConsumptionData(self):
try:
# updateBearerToken
url = "https://oidc.car-cloud.org/auth/realms/OEM/protocol/openid-connect/token"
par = { "grant_type" : "client_credentials",
"client_id":"etron-rp",
"client_secret":"e7b479bf-df6e-4513-9565-0283d5873f50",
}
start = time.perf_counter()
response = requests.post(url,data=par,timeout=300).json()
request_time_token = time.perf_counter() - start
print('time get token: %s sec'%str(round(request_time_token,3)))
ac_token = response['access_token']
url_cs = "https://cariad-routing.tui.car-cloud.org/consumptionData?"
print(url_cs)
parameter = { "modelcode":(self.textEdit_consumptionData.toPlainText()),
}
head = {
'Authorization': 'Bearer ' + ac_token
}
start = time.perf_counter()
response = requests.get(url_cs,params=parameter,headers=head,timeout=300)
request_time = round(time.perf_counter() - start,3)
#print('DateTime: %s\nReqest time: %s\nRespones URL: %s\nResponse: %s\n#######################\n\n'%(str(datetime.datetime.now()),str(request_time),str(response.url),str(response)))
self.label_showVehicleData.append('### show vehicle consumption data ###')
self.label_showVehicleData.append('DateTime: '+str(datetime.datetime.now()))
self.label_showVehicleData.append('Reqest time: '+str(request_time))
self.label_showVehicleData.append('Respones URL: '+str(response.url))
try:
self.label_showVehicleData.append('Response: '+str(response.json()))
except:
print('ERROR: sevice not reachable')
self.label_showVehicleData.append('Response: '+str(response))
self.label_showVehicleData.append('############################################')
except Exception as e:
print("ERROR : "+str(e))
def setStart(self):
try:
url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + str(self.textEdit_from.toPlainText()) + '.json'
parameters = {'access_token':cfg.conf['key_MapBox']}
lat_s,lng_s = requests.get(url,params=parameters,timeout=300).json()['features'][0]['center']
url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + str(self.textEdit_to.toPlainText()) + '.json'
parameters = {'access_token':cfg.conf['key_MapBox']}
lat_d,lng_d = requests.get(url,params=parameters,timeout=300).json()['features'][0]['center']
#############################
### CariadRouting (LDEVR) ###
#############################
# updateBearerToken
url = "https://oidc.car-cloud.org/auth/realms/OEM/protocol/openid-connect/token"
par = { "grant_type" : "client_credentials",
"client_id":"etron-rp",
"client_secret":"e7b479bf-df6e-4513-9565-0283d5873f50",
}
start = time.perf_counter()
response = requests.post(url,data=par,timeout=300).json()
request_time_token = time.perf_counter() - start
print('time get token: %s sec'%str(round(request_time_token,3)))
ac_token = response['access_token']
parameter = { "vin":int(self.textEdit_VIN.toPlainText()),
"latStart":lng_s,
"longStart":lat_s,
"latDestination":lng_d,
"longDestination":lat_d,
}
#url_cs = "https://cariad-routing.tui.car-cloud.org/calculateRoute?"
url_cs = self.combo_box_url.currentText()
print(url_cs)
head = {
'Authorization': 'Bearer ' + ac_token
}
start = time.perf_counter()
response = requests.get(url_cs,params=parameter,headers=head,timeout=300)
request_time = round(time.perf_counter() - start,3)
print(response.url)
response = response.json()
#print(response)
# ToDo change + get from vehicle
par={'maxChargeInkWh':92,
'currentChargeInkWh':9,
'minChargeAtDestinationInkWh':4.2,
'minChargeAtChargingStopsInkWh':5,
}
#add the CARIAD Routing request time
self.textBrowser_responseTime.append(str(request_time))
try:
lat = []
lng = []
lat_ch = []
lng_ch = []
time_ch = [] # charging time
arrival_energy = []
target_energy = []
charging_power = []
facility_info = []
leg_distance = []
chargingPark_name = []
ch_info_type = []
for i in range(len(response['routes'][0]['legs'])):
boundary = response['routes'][0]['legs'][i]['points']
lat_ch.append(response['routes'][0]['legs'][i]['points'][-1]['latitude'])
lng_ch.append(response['routes'][0]['legs'][i]['points'][-1]['longitude'])
try:
time_ch.append(response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingTimeInSeconds']/60)
arrival_energy.append(response['routes'][0]['legs'][i]['summary']['remainingChargeAtArrivalInkWh'])
target_energy.append(response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['targetChargeInkWh'])
charging_power.append((response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['targetChargeInkWh']
-response['routes'][0]['legs'][i]['summary']['remainingChargeAtArrivalInkWh'])
/(response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingTimeInSeconds']/3600))
leg_distance.append(response['routes'][0]['legs'][i]['summary']['lengthInMeters'])
chargingPark_name.append(response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingParkName'])
try:
ch_info_type.append("<ul> <li>ch. voltage %d [V] </li> <li>ch. current %d [A]</li> <li>ch. type %s </li> <li>ch. power %d [kW]</li> <li>ch. PlugType %s</li> </ul>" % (
response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingConnectionInfo']['chargingVoltageInV'],
response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingConnectionInfo']['chargingCurrentInA'],
response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingConnectionInfo']['chargingCurrentType'],
response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingConnectionInfo']['chargingPowerInkW'],
response['routes'][0]['legs'][i]['summary']['chargingInformationAtEndOfLeg']['chargingConnectionInfo']['chargingPlugType']
)
)
except:
ch_info_type.append("")
pass
except:
pass
for d in boundary:
lat.append(d['latitude'])
lng.append(d['longitude'])
# delete destination point
lat_ch=lat_ch[:-1]
lng_ch=lng_ch[:-1]
time_r = request_time # s
distance = response['routes'][0]['summary']['lengthInMeters']/1000 # km
travel_time = response['routes'][0]['summary']['travelTimeInSeconds']/60 # min
traffic_time = response['routes'][0]['summary']['trafficDelayInSeconds']/60 # min
charging_time = response['routes'][0]['summary']['totalChargingTimeInSeconds']/60 # min
charging_stops = len(lat_ch) # amount of charging stops
arrival_energy_g = response['routes'][0]['summary']['remainingChargeAtArrivalInkWh']
total_energy = response['routes'][0]['summary']['batteryConsumptionInkWh']
if len(lat_ch)==0:
lat_ch = 0
lng_ch = 0
Tab=[]
Tab.append([lat,lng,lat_ch,lng_ch,time_r,distance,travel_time,traffic_time,charging_time,charging_stops,time_ch,arrival_energy,target_energy,charging_power,facility_info,'CARIAD Routing',arrival_energy_g,total_energy,leg_distance,chargingPark_name,ch_info_type])
### Google Plot ###
apikey = cfg.conf['key_Google'] # (your API key here)
# GoogleMapPlotter return Map object
# Pass the center latitude and center longitude
gmap = gmplot.GoogleMapPlotter((lng_s+lng_d)/2,
(lat_s+lat_d)/2,
7,
apikey=apikey)
color = ['#B22222','#1E90FF','#C0C0C0','#008000','#BDB76B','#FF8C00','#7FFFD4','#807673','#B22222','#B22222','#1E90FF','#C0C0C0','#008000','#BDB76B','#FF8C00','#7FFFD4','#807673','#B22222','#B22222','#1E90FF','#C0C0C0','#008000','#BDB76B','#FF8C00','#7FFFD4','#807673','#B22222']
for i in range(len(Tab)):
if Tab[i] != 'No Route Found':
gmap.plot(
(Tab[i][0]),
(Tab[i][1]),
color=color[i],
edge_width=12-2*i,
label=('%s Routing' % Tab[i][15]),
alpha=1-(i/10)
)
if Tab[i][3] != 0:
acc_d = 0
for j in range(len(Tab[i][2])): # iterate through charging stations
acc_d = acc_d+Tab[i][18][j]/1000
gmap.marker(
(Tab[i][2][j]),
(Tab[i][3][j]),
color=color[i],
label=('%d'%(j+1)),
info_window=('<div id="content">' + '<div id="siteNotice">' + "</div>" + '<h1 id="firstHeading" class="firstHeading">' + ('%d - %s Charging' % (j+1,Tab[i][15])) + '</h1>' + '<div id="bodyContent">' + ("charging time %.2f [min] <br>arrival energy %.2f [kWh] (%.2f %%)<br>target energy %.2f [kWh] (%.2f %%)<br>calculated power %.2f kW <br>Distance of the leg %.2f [km] <br>Acc distance of legs %.2f [km] <br>Charging Name: %s <br>Charging Info: <br> %s" % (Tab[i][10][j],Tab[i][11][j],Tab[i][11][j]/par['maxChargeInkWh']*100,Tab[i][12][j],Tab[i][12][j]/par['maxChargeInkWh']*100,Tab[i][13][j],Tab[i][18][j]/1000,acc_d,Tab[i][19][j],Tab[i][20][j])) + "</div>" + "</div>"),
marker=True,
title=('%d - %s charging' % (j+1,Tab[i][15])),
)
gmap.marker(
lng_s,
lat_s,
label='S',
info_window=('<div id="content">' + '<div id="siteNotice">' + "</div>" + '<h1 id="firstHeading" class="firstHeading">' + ('%s Start Point' % (Tab[i][15])) + '</h1>' + '<div id="bodyContent">' + ("start energy %.2f [kWh] (%.2f %%) <br> max. Energy %.2f [kWh] <br>Setting: min. charge at Destination %.2f [kWh] (%.2f %%) <br>Setting: min. charge at Charging Stops %.2f [kWh] (%.2f %%) " % (par['currentChargeInkWh'],par['currentChargeInkWh']/par['maxChargeInkWh']*100,par['maxChargeInkWh'],par['minChargeAtDestinationInkWh'],par['minChargeAtDestinationInkWh']/par['maxChargeInkWh']*100,par['minChargeAtChargingStopsInkWh'],par['minChargeAtChargingStopsInkWh']/par['maxChargeInkWh']*100)) + "</div>" + "</div>"),
)
gmap.marker(
lng_d,
lat_d,
label='D',
info_window=('<div id="content">' + '<div id="siteNotice">' + "</div>" + '<h1 id="firstHeading" class="firstHeading">' + ('%s Destination Point' % (Tab[i][15])) + '</h1>' + '<div id="bodyContent">' + ("arrival energy %.2f [kWh] (%.2f %%) <br> total amount of energy %.2f [kWh] (%.2f %%) <br>charging stopps %.0f [-] <br>summary of charging time %.2f [min] <br>traffic delay time %.2f [min] <br>travel time %.2f [min] <br>total distance %.2f [km] <br>response time %.2f[s]" % (Tab[i][16],Tab[i][16]/par['maxChargeInkWh']*100,Tab[i][17],Tab[i][17]/par['maxChargeInkWh']*100,Tab[i][9],Tab[i][8],Tab[i][7],Tab[i][6],Tab[i][5],Tab[i][4])) + "</div>" + "</div>"),
)
gmap.draw("figures/Routing_onMap.html")
local_url = QUrl.fromLocalFile(os.path.abspath("./figures/Routing_onMap.html"))
self.label_map.load(local_url)
self.label_map.setZoomFactor(1.25)
except:
print(response)
local_url = QUrl.fromLocalFile(os.path.abspath("./figures/error.html"))
self.label_map.load(local_url)
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setText(str(response))
msg.setWindowTitle("Warning MessageBox")
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
retval = msg.exec_()
except Exception as e:
print("Bad Input")
print("ERROR : "+str(e))
local_url = QUrl.fromLocalFile(os.path.abspath("./figures/error.html"))
self.label_map.load(local_url)
def setDestination(self):
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setText('!RangeOnMap (360 Range) coming soon!')
msg.setWindowTitle("Warning MessageBox")
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
retval = msg.exec_()
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyleSheet('QMainWindow{border: 2px solid gray;}')
ex = App()
sys.exit(app.exec_())