Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smarteq SOC Modul: 2FA, MBAPI #1582

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Conversation

rleidner
Copy link
Collaborator

Adding

@benderl benderl added the enhancement New feature or request label Apr 25, 2024
@benderl benderl requested a review from LKuemmel April 25, 2024 07:46
@benderl benderl added this to the 2.4.2 milestone Apr 25, 2024
@rleidner
Copy link
Collaborator Author

Wie in bmwbc auf context handler umgestellt.

@rleidner
Copy link
Collaborator Author

Websocket interface hat seit 28.05.2024 nicht mehr funktioniert.
In der MB cloud wurden APP-Versionen geändert - das wurde nachgezogen.
Token Refresh im websocket mode von 1 Woche auf 1 Stunde geändert - das scheint jetzt stabil zu laufen.

@rleidner rleidner requested a review from benderl June 17, 2024 13:32
@rleidner
Copy link
Collaborator Author

Konflikt in requirements.txt behoben.

Copy link
Contributor

@LKuemmel LKuemmel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das Logging wird so definitiv nicht gemergt.
Im Forum klappt es oft schon nicht, dass Log-Dateien im Level Details gepostet werden. Ein normaler Endbenutzer wird nicht die richtige Option auswählen können. Deshalb wird im Loglevel Details alles für die Fehlersuche notwendige geloggt, damit die Kunden lediglich das Log hochladen müssen und Hilfe bekommen und nicht schon vor der Fehlersuche so viel nachgefragt werden muss.
Ich denke, man kann das Logging insgesamt noch etwas entschlacken. Ich habe ein paar Stellen aufgezeigt.

packages/modules/vehicles/smarteq/api.py Outdated Show resolved Hide resolved
packages/modules/vehicles/smarteq/api.py Outdated Show resolved Hide resolved
packages/modules/vehicles/smarteq/api.py Outdated Show resolved Hide resolved
Comment on lines 204 to 221
def set_CarState(self, ev: int, soc: int, range: float, ts: int):
try:
msgs = []
topic = 'openWB/set/vehicle/' + str(ev) + '/get/soc'
# self.pub(topic, str(soc))
msgs.append({'topic': topic, 'payload': str(soc)})
topic = 'openWB/set/vehicle/' + str(ev) + '/get/range'
# self.pub(topic, str(range))
msgs.append({'topic': topic, 'payload': str(range)})
topic = 'openWB/set/vehicle/' + str(ev) + '/get/soc_timestamp'
_ts = time.time()
# self.pub(topic, str(_ts))
msgs.append({'topic': topic, 'payload': str(_ts)})
_infoLog('Q', "set_CarState publish.multiple: msgs=\n" + json.dumps(msgs))
_infoLog('q', "set_CarState: " + str(soc) + '%/' + str(range) + 'KM@' + str(_ts))
publish.multiple(msgs, hostname='localhost', port=1883)
except Exception as e:
log.exception("set_CarState error: %s", e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bitte nur den CarState zurückgeben und Publishen, Fehlerbehandlung etc vom Backend erledigen lassen. Wenn jedes Modul seine eigene Implementierung nutzt, wird die Wartung des Codes schnell sehr sehr aufwändig.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das Return-Interface püass für das im smarteq benutzte Mercedes-API halt nicht.
Das SOC-Modul subscribed die Daten über Websockets.
Die Fahrzeug-Daten kommen asynchron über WebSockets ca. alle 15 Sekunden.
Wenn sich Soc oder range ändern schreibt das Modul die Daten über diese Funktion in den CarState.

Ich habe mittlerweile eine Alternative über den store:
# publish CarState via core store
def set_CarState(self, vehicle: int, soc: int, range: float, ts: int):
try:
st: CarValueStoreBroker = store.get_car_value_store(vehicle)
carState: CarState = CarState(int(soc), float(range), round(time(), 2))
st.set(carState)
st.update()
except Exception as e:
log.exception("set_CarState Error: %s", e)
return

Wäre das ein akzeptabler Weg?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich habe jetzt die "API" über den store implementiert wie oben.

Comment on lines 1176 to 1188
self.ws_soc = str(-1)
self.ws_range = str(0.0)
self.ws_soc_ts = 'na'
self.write_ws_store(self.vin)
self.wsError = 1

def ws_on_close(self, ws, status_code, message):
self._infoLog('w', "ws_on_close, status_code=" + str(status_code) +
", message=" + str(message))
self.ws_soc = str(-1)
self.ws_range = str(0.0)
self.ws_soc_ts = 'na'
self.write_ws_store(self.vin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wenn die Abfrage fehl schlägt, bitte eine Exception werfen und keine Standardwerte setzen. Wird die Abfrage dreimal mit einer Exception abgebrochen, startet das Backend bei SoC-geführtem Lademodus die Ladung, damit man nicht mit einem leeren Auto da steht, weil der Server nicht erreichbar war.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das passiert in dem Websocket thread und signalisiert der nächsten regulären Abfrage, dass die WebSocket-Schnittstelle keine Daten liefern konnte...

Comment on lines 87 to 101
def read_token_file(self, path: str) -> str:
try:
with open(path, "r") as tf: # try to open Token file
token = tf.read() # read token
except Exception:
token = None # if no old token found set Token_old to dummy value
return token

def write_token_file(self, path: str, token: str, config={}):
try:
_infoLog('s', "store Token in file " + path)
with open(path, "w") as tf:
tf.write(token) # write Token file
except Exception as e:
log.exception('Token file write exception ' + str(e))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die tokens werden im Broker gespeichert, warum nochmal in eine Datei?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im broker wird aktuell nur der refresh.token gespeichert.
In der Ramdisk-Datei werden alle vom Server gelieferten Daten gespeichert.
Bei smarteq/mercedes macht das wenig Unterschied, das refresh- und access-token die gleiche Gültigkeit von 2 Stunden haben.
Bei VWId ist der Access-Token auch recht kurz gültig, der refresh-token (JWT) dagegen gilt für ca. 6 Monate, d.h. im broker wird nur sehr selten gespeichert.

Comment on lines 121 to 122
self.ws_storeFile = str(RAMDISK_PATH) + '/soc_smarteq_store_ws'
self.messageFile = str(RAMDISK_PATH) + '/soc_smarteq_message_vh_' + str(vehicle)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was sind das für Dateien, die hier geschrieben werden? Die Tokens sollten im Broker, der SoC im Rückgabewert und alles andere im Log landen.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ws_storeFile ist eine Datei, in der die Daten der websocket-Schnittstelle gespeichert werden Beispiel:

    "vin": "WME4530911Y181749",
    "soc": "92",
    "range": "113",
    "ws_soc_ts": "2024-06-19 15:50:22",
    "ws_ts": 1718805022,
    "ws_connect_time": 0,
    "connect_time": "1718803134"
}````
Diese Datei hat die VIN im Namen und wird daher je VIN geschrieben.
Der "normale" SOC-Abruf kann damit ohne REST-Abruf direkt die Daten verwenden.
messageFile ist zum Test/Analyse gedacht.
Die Websocket-Schnittstelle liefert einige Message-Typen.
Die ankommenden Messages werden per typ in die Ramdisk geschrieben.
Damit lässt sich erkennen wenn sich die Daten einmal ändern sollten.

@rleidner
Copy link
Collaborator Author

Hi Lena,
ein sehr lästiges Problem des globalen debug Levels:
Ich habe momentan in meinem 2.0 Testsystem 4 verschiedene Fahrzeuge / SOC-Module eingerichtet.
Wenn logging auf DEBUG steht schreiben jetzt alle soc-Module aus allen Rohren in den soc.log.
Dabei bin ich nur an den DEBUG-Ausgaben eines Moduls interessiert!
Die main.log wird natürlich auch unnötigerweise extrem zugemüllt.
Da hat mein logFilter sehr viel intelligenter agiert.
Grüsse Rainer

@rleidner rleidner requested a review from LKuemmel June 21, 2024 09:49
@LKuemmel
Copy link
Contributor

Ja, das Log ist sehr umfangreich. deshalb steht bei jeder Logausgabe von welchem Fahrzeug sie stammt. Aber dadurch ist es einfach im Forum ohne viele Rückfragen an die benötigten Informationen zu kommen.
Und zuletzt hat die Einstellung des Logs nichts in den Moduleinstellungen zu suchen, da sie keinen Einfluss auf die Funktionaltität hat und ein normaler Endbenutzer darüber stolpern wird, weil er nicht weiß, was er dort einstellen soll bzw das er dort nichts einstellen muss.

@rleidner
Copy link
Collaborator Author

Hallo Lutz und Lena,
ich habe vor 3 Wochen alle im Review hochgekommenen Änderungswünsche eingearbeitet.
Bitte seht Euch das an und lasst mich wissen ob es jetzt OK ist oder wo noch Probleme sind.
Das Modul läuft bei mir im Testsystem mittlerweile seit Monaten ohne Problem.
VG
Rainer

@benderl
Copy link
Contributor

benderl commented Jul 11, 2024

Hallo Rainer,
ich war die letzten Wochen im Urlaub und Lena hatte reichlich zu tun. Wir werden uns in den nächsten Tagen drum kümmern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants